diff options
Diffstat (limited to 'fs')
432 files changed, 8042 insertions, 6026 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index 56d88c1a09c5..a3ed571eee31 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include "debug.h" | 33 | #include "debug.h" |
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c index 8556097fcda8..dc336a67592f 100644 --- a/fs/9p/fcall.c +++ b/fs/9p/fcall.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | 32 | ||
32 | #include "debug.h" | 33 | #include "debug.h" |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 70492ccb4385..27507201f9e7 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/sched.h> | ||
26 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
27 | 28 | ||
28 | #include "debug.h" | 29 | #include "debug.h" |
diff --git a/fs/9p/mux.c b/fs/9p/mux.c index 90a79c784549..944273c3dbff 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c | |||
@@ -110,8 +110,8 @@ struct v9fs_mux_rpc { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | static int v9fs_poll_proc(void *); | 112 | static int v9fs_poll_proc(void *); |
113 | static void v9fs_read_work(void *); | 113 | static void v9fs_read_work(struct work_struct *work); |
114 | static void v9fs_write_work(void *); | 114 | static void v9fs_write_work(struct work_struct *work); |
115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, |
116 | poll_table * p); | 116 | poll_table * p); |
117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); | 117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); |
@@ -297,8 +297,8 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
297 | m->rbuf = NULL; | 297 | m->rbuf = NULL; |
298 | m->wpos = m->wsize = 0; | 298 | m->wpos = m->wsize = 0; |
299 | m->wbuf = NULL; | 299 | m->wbuf = NULL; |
300 | INIT_WORK(&m->rq, v9fs_read_work, m); | 300 | INIT_WORK(&m->rq, v9fs_read_work); |
301 | INIT_WORK(&m->wq, v9fs_write_work, m); | 301 | INIT_WORK(&m->wq, v9fs_write_work); |
302 | m->wsched = 0; | 302 | m->wsched = 0; |
303 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 303 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
304 | m->poll_task = NULL; | 304 | m->poll_task = NULL; |
@@ -458,13 +458,13 @@ static int v9fs_poll_proc(void *a) | |||
458 | /** | 458 | /** |
459 | * v9fs_write_work - called when a transport can send some data | 459 | * v9fs_write_work - called when a transport can send some data |
460 | */ | 460 | */ |
461 | static void v9fs_write_work(void *a) | 461 | static void v9fs_write_work(struct work_struct *work) |
462 | { | 462 | { |
463 | int n, err; | 463 | int n, err; |
464 | struct v9fs_mux_data *m; | 464 | struct v9fs_mux_data *m; |
465 | struct v9fs_req *req; | 465 | struct v9fs_req *req; |
466 | 466 | ||
467 | m = a; | 467 | m = container_of(work, struct v9fs_mux_data, wq); |
468 | 468 | ||
469 | if (m->err < 0) { | 469 | if (m->err < 0) { |
470 | clear_bit(Wworksched, &m->wsched); | 470 | clear_bit(Wworksched, &m->wsched); |
@@ -564,7 +564,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
564 | /** | 564 | /** |
565 | * v9fs_read_work - called when there is some data to be read from a transport | 565 | * v9fs_read_work - called when there is some data to be read from a transport |
566 | */ | 566 | */ |
567 | static void v9fs_read_work(void *a) | 567 | static void v9fs_read_work(struct work_struct *work) |
568 | { | 568 | { |
569 | int n, err; | 569 | int n, err; |
570 | struct v9fs_mux_data *m; | 570 | struct v9fs_mux_data *m; |
@@ -572,7 +572,7 @@ static void v9fs_read_work(void *a) | |||
572 | struct v9fs_fcall *rcall; | 572 | struct v9fs_fcall *rcall; |
573 | char *rbuf; | 573 | char *rbuf; |
574 | 574 | ||
575 | m = a; | 575 | m = container_of(work, struct v9fs_mux_data, rq); |
576 | 576 | ||
577 | if (m->err < 0) | 577 | if (m->err < 0) |
578 | return; | 578 | return; |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 0f628041e3f7..0b96fae8b479 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/sched.h> | ||
29 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | 32 | ||
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 9dfd259a70b4..cc24abf232d5 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -54,7 +54,7 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page) | |||
54 | int retval = -EIO; | 54 | int retval = -EIO; |
55 | loff_t offset = page_offset(page); | 55 | loff_t offset = page_offset(page); |
56 | int count = PAGE_CACHE_SIZE; | 56 | int count = PAGE_CACHE_SIZE; |
57 | struct inode *inode = filp->f_dentry->d_inode; | 57 | struct inode *inode = filp->f_path.dentry->d_inode; |
58 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 58 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
59 | int rsize = v9ses->maxdata - V9FS_IOHDRSZ; | 59 | int rsize = v9ses->maxdata - V9FS_IOHDRSZ; |
60 | struct v9fs_fid *v9f = filp->private_data; | 60 | struct v9fs_fid *v9f = filp->private_data; |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index e32d5971039b..3129688143ea 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/sched.h> | ||
33 | #include <linux/inet.h> | 34 | #include <linux/inet.h> |
34 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
35 | 36 | ||
@@ -70,7 +71,7 @@ static inline int dt_type(struct v9fs_stat *mistat) | |||
70 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | 71 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) |
71 | { | 72 | { |
72 | struct v9fs_fcall *fcall = NULL; | 73 | struct v9fs_fcall *fcall = NULL; |
73 | struct inode *inode = filp->f_dentry->d_inode; | 74 | struct inode *inode = filp->f_path.dentry->d_inode; |
74 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 75 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
75 | struct v9fs_fid *file = filp->private_data; | 76 | struct v9fs_fid *file = filp->private_data; |
76 | unsigned int i, n, s; | 77 | unsigned int i, n, s; |
@@ -79,7 +80,7 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
79 | struct v9fs_stat stat; | 80 | struct v9fs_stat stat; |
80 | int over = 0; | 81 | int over = 0; |
81 | 82 | ||
82 | dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name); | 83 | dprintk(DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); |
83 | 84 | ||
84 | fid = file->fid; | 85 | fid = file->fid; |
85 | 86 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c3c47eda7574..e86a07151280 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/sched.h> | ||
29 | #include <linux/file.h> | 30 | #include <linux/file.h> |
30 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 32 | #include <linux/string.h> |
@@ -59,7 +60,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
59 | 60 | ||
60 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); | 61 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
61 | 62 | ||
62 | vfid = v9fs_fid_lookup(file->f_dentry); | 63 | vfid = v9fs_fid_lookup(file->f_path.dentry); |
63 | if (!vfid) { | 64 | if (!vfid) { |
64 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); | 65 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); |
65 | return -EBADF; | 66 | return -EBADF; |
@@ -132,7 +133,7 @@ free_fcall: | |||
132 | static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) | 133 | static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) |
133 | { | 134 | { |
134 | int res = 0; | 135 | int res = 0; |
135 | struct inode *inode = filp->f_dentry->d_inode; | 136 | struct inode *inode = filp->f_path.dentry->d_inode; |
136 | 137 | ||
137 | dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); | 138 | dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); |
138 | 139 | ||
@@ -160,7 +161,7 @@ static ssize_t | |||
160 | v9fs_file_read(struct file *filp, char __user * data, size_t count, | 161 | v9fs_file_read(struct file *filp, char __user * data, size_t count, |
161 | loff_t * offset) | 162 | loff_t * offset) |
162 | { | 163 | { |
163 | struct inode *inode = filp->f_dentry->d_inode; | 164 | struct inode *inode = filp->f_path.dentry->d_inode; |
164 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 165 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
165 | struct v9fs_fid *v9f = filp->private_data; | 166 | struct v9fs_fid *v9f = filp->private_data; |
166 | struct v9fs_fcall *fcall = NULL; | 167 | struct v9fs_fcall *fcall = NULL; |
@@ -224,7 +225,7 @@ static ssize_t | |||
224 | v9fs_file_write(struct file *filp, const char __user * data, | 225 | v9fs_file_write(struct file *filp, const char __user * data, |
225 | size_t count, loff_t * offset) | 226 | size_t count, loff_t * offset) |
226 | { | 227 | { |
227 | struct inode *inode = filp->f_dentry->d_inode; | 228 | struct inode *inode = filp->f_path.dentry->d_inode; |
228 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 229 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
229 | struct v9fs_fid *v9fid = filp->private_data; | 230 | struct v9fs_fid *v9fid = filp->private_data; |
230 | struct v9fs_fcall *fcall; | 231 | struct v9fs_fcall *fcall; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 5241c600ce28..18f26cdfd882 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -256,7 +256,7 @@ static int | |||
256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, | 256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, |
257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | 257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) |
258 | { | 258 | { |
259 | u32 fid; | 259 | int fid; |
260 | int err; | 260 | int err; |
261 | struct v9fs_fcall *fcall; | 261 | struct v9fs_fcall *fcall; |
262 | 262 | ||
@@ -310,7 +310,7 @@ static struct v9fs_fid* | |||
310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) | 310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) |
311 | { | 311 | { |
312 | int err; | 312 | int err; |
313 | u32 nfid; | 313 | int nfid; |
314 | struct v9fs_fid *ret; | 314 | struct v9fs_fid *ret; |
315 | struct v9fs_fcall *fcall; | 315 | struct v9fs_fcall *fcall; |
316 | 316 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index 7b1511d50b05..8cd2417a14db 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -12,9 +12,7 @@ config EXT2_FS | |||
12 | Ext2 is a standard Linux file system for hard disks. | 12 | Ext2 is a standard Linux file system for hard disks. |
13 | 13 | ||
14 | To compile this file system support as a module, choose M here: the | 14 | To compile this file system support as a module, choose M here: the |
15 | module will be called ext2. Be aware however that the file system | 15 | module will be called ext2. |
16 | of your root partition (the one containing the directory /) cannot | ||
17 | be compiled as a module, and so this could be dangerous. | ||
18 | 16 | ||
19 | If unsure, say Y. | 17 | If unsure, say Y. |
20 | 18 | ||
@@ -98,9 +96,7 @@ config EXT3_FS | |||
98 | (available at <http://sourceforge.net/projects/e2fsprogs/>). | 96 | (available at <http://sourceforge.net/projects/e2fsprogs/>). |
99 | 97 | ||
100 | To compile this file system support as a module, choose M here: the | 98 | To compile this file system support as a module, choose M here: the |
101 | module will be called ext3. Be aware however that the file system | 99 | module will be called ext3. |
102 | of your root partition (the one containing the directory /) cannot | ||
103 | be compiled as a module, and so this may be dangerous. | ||
104 | 100 | ||
105 | config EXT3_FS_XATTR | 101 | config EXT3_FS_XATTR |
106 | bool "Ext3 extended attributes" | 102 | bool "Ext3 extended attributes" |
@@ -163,9 +159,7 @@ config EXT4DEV_FS | |||
163 | features will be added to ext4dev gradually. | 159 | features will be added to ext4dev gradually. |
164 | 160 | ||
165 | To compile this file system support as a module, choose M here. The | 161 | To compile this file system support as a module, choose M here. The |
166 | module will be called ext4dev. Be aware, however, that the filesystem | 162 | module will be called ext4dev. |
167 | of your root partition (the one containing the directory /) cannot | ||
168 | be compiled as a module, and so this could be dangerous. | ||
169 | 163 | ||
170 | If unsure, say N. | 164 | If unsure, say N. |
171 | 165 | ||
@@ -972,7 +966,7 @@ config SYSFS | |||
972 | 966 | ||
973 | Some system agents rely on the information in sysfs to operate. | 967 | Some system agents rely on the information in sysfs to operate. |
974 | /sbin/hotplug uses device and object attributes in sysfs to assist in | 968 | /sbin/hotplug uses device and object attributes in sysfs to assist in |
975 | delegating policy decisions, like persistantly naming devices. | 969 | delegating policy decisions, like persistently naming devices. |
976 | 970 | ||
977 | sysfs is currently used by the block subsystem to mount the root | 971 | sysfs is currently used by the block subsystem to mount the root |
978 | partition. If sysfs is disabled you must specify the boot device on | 972 | partition. If sysfs is disabled you must specify the boot device on |
@@ -1008,7 +1002,7 @@ config TMPFS_POSIX_ACL | |||
1008 | 1002 | ||
1009 | config HUGETLBFS | 1003 | config HUGETLBFS |
1010 | bool "HugeTLB file system support" | 1004 | bool "HugeTLB file system support" |
1011 | depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN | 1005 | depends on X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN |
1012 | help | 1006 | help |
1013 | hugetlbfs is a filesystem backing for HugeTLB pages, based on | 1007 | hugetlbfs is a filesystem backing for HugeTLB pages, based on |
1014 | ramfs. For architectures that support it, say Y here and read | 1008 | ramfs. For architectures that support it, say Y here and read |
@@ -1145,7 +1139,7 @@ config BEFS_FS | |||
1145 | help | 1139 | help |
1146 | The BeOS File System (BeFS) is the native file system of Be, Inc's | 1140 | The BeOS File System (BeFS) is the native file system of Be, Inc's |
1147 | BeOS. Notable features include support for arbitrary attributes | 1141 | BeOS. Notable features include support for arbitrary attributes |
1148 | on files and directories, and database-like indeces on selected | 1142 | on files and directories, and database-like indices on selected |
1149 | attributes. (Also note that this driver doesn't make those features | 1143 | attributes. (Also note that this driver doesn't make those features |
1150 | available at this time). It is a 64 bit filesystem, so it supports | 1144 | available at this time). It is a 64 bit filesystem, so it supports |
1151 | extremely large volumes and files. | 1145 | extremely large volumes and files. |
@@ -1204,13 +1198,16 @@ config EFS_FS | |||
1204 | 1198 | ||
1205 | config JFFS_FS | 1199 | config JFFS_FS |
1206 | tristate "Journalling Flash File System (JFFS) support" | 1200 | tristate "Journalling Flash File System (JFFS) support" |
1207 | depends on MTD && BLOCK | 1201 | depends on MTD && BLOCK && BROKEN |
1208 | help | 1202 | help |
1209 | JFFS is the Journalling Flash File System developed by Axis | 1203 | JFFS is the Journalling Flash File System developed by Axis |
1210 | Communications in Sweden, aimed at providing a crash/powerdown-safe | 1204 | Communications in Sweden, aimed at providing a crash/powerdown-safe |
1211 | file system for disk-less embedded devices. Further information is | 1205 | file system for disk-less embedded devices. Further information is |
1212 | available at (<http://developer.axis.com/software/jffs/>). | 1206 | available at (<http://developer.axis.com/software/jffs/>). |
1213 | 1207 | ||
1208 | NOTE: This filesystem is deprecated and is scheduled for removal in | ||
1209 | 2.6.21. See Documentation/feature-removal-schedule.txt | ||
1210 | |||
1214 | config JFFS_FS_VERBOSE | 1211 | config JFFS_FS_VERBOSE |
1215 | int "JFFS debugging verbosity (0 = quiet, 3 = noisy)" | 1212 | int "JFFS debugging verbosity (0 = quiet, 3 = noisy)" |
1216 | depends on JFFS_FS | 1213 | depends on JFFS_FS |
diff --git a/fs/Makefile b/fs/Makefile index 9a5ce9323bfd..b9ffa63f77fc 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -10,7 +10,8 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
10 | ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ | 10 | ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ |
11 | attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ |
12 | seq_file.o xattr.o libfs.o fs-writeback.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
13 | pnode.o drop_caches.o splice.o sync.o utimes.o | 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ |
14 | stack.o | ||
14 | 15 | ||
15 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
16 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o | 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index d3c7905b2ddc..2b8903893d3f 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -28,7 +28,7 @@ static DEFINE_RWLOCK(adfs_dir_lock); | |||
28 | static int | 28 | static int |
29 | adfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 29 | adfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
30 | { | 30 | { |
31 | struct inode *inode = filp->f_dentry->d_inode; | 31 | struct inode *inode = filp->f_path.dentry->d_inode; |
32 | struct super_block *sb = inode->i_sb; | 32 | struct super_block *sb = inode->i_sb; |
33 | struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir; | 33 | struct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir; |
34 | struct object_info obj; | 34 | struct object_info obj; |
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index bbfc86259272..b9b2b27b68c3 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c | |||
@@ -53,7 +53,7 @@ static inline int adfs_readname(char *buf, char *ptr, int maxlen) | |||
53 | { | 53 | { |
54 | char *old_buf = buf; | 54 | char *old_buf = buf; |
55 | 55 | ||
56 | while (*ptr >= ' ' && maxlen--) { | 56 | while ((unsigned char)*ptr >= ' ' && maxlen--) { |
57 | if (*ptr == '/') | 57 | if (*ptr == '/') |
58 | *buf++ = '.'; | 58 | *buf++ = '.'; |
59 | else | 59 | else |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 9ade139086fc..5023351a7afe 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -36,7 +36,7 @@ void __adfs_error(struct super_block *sb, const char *function, const char *fmt, | |||
36 | va_list args; | 36 | va_list args; |
37 | 37 | ||
38 | va_start(args, fmt); | 38 | va_start(args, fmt); |
39 | vsprintf(error_buf, fmt, args); | 39 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
40 | va_end(args); | 40 | va_end(args); |
41 | 41 | ||
42 | printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n", | 42 | printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n", |
@@ -212,12 +212,12 @@ static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
212 | return 0; | 212 | return 0; |
213 | } | 213 | } |
214 | 214 | ||
215 | static kmem_cache_t *adfs_inode_cachep; | 215 | static struct kmem_cache *adfs_inode_cachep; |
216 | 216 | ||
217 | static struct inode *adfs_alloc_inode(struct super_block *sb) | 217 | static struct inode *adfs_alloc_inode(struct super_block *sb) |
218 | { | 218 | { |
219 | struct adfs_inode_info *ei; | 219 | struct adfs_inode_info *ei; |
220 | ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, SLAB_KERNEL); | 220 | ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, GFP_KERNEL); |
221 | if (!ei) | 221 | if (!ei) |
222 | return NULL; | 222 | return NULL; |
223 | return &ei->vfs_inode; | 223 | return &ei->vfs_inode; |
@@ -228,7 +228,7 @@ static void adfs_destroy_inode(struct inode *inode) | |||
228 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); | 228 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); |
229 | } | 229 | } |
230 | 230 | ||
231 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 231 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
232 | { | 232 | { |
233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; | 233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; |
234 | 234 | ||
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index ccd624ef4272..f4de4b98004f 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -445,7 +445,7 @@ affs_error(struct super_block *sb, const char *function, const char *fmt, ...) | |||
445 | va_list args; | 445 | va_list args; |
446 | 446 | ||
447 | va_start(args,fmt); | 447 | va_start(args,fmt); |
448 | vsprintf(ErrorBuffer,fmt,args); | 448 | vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); |
449 | va_end(args); | 449 | va_end(args); |
450 | 450 | ||
451 | printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id, | 451 | printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id, |
@@ -461,7 +461,7 @@ affs_warning(struct super_block *sb, const char *function, const char *fmt, ...) | |||
461 | va_list args; | 461 | va_list args; |
462 | 462 | ||
463 | va_start(args,fmt); | 463 | va_start(args,fmt); |
464 | vsprintf(ErrorBuffer,fmt,args); | 464 | vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); |
465 | va_end(args); | 465 | va_end(args); |
466 | 466 | ||
467 | printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id, | 467 | printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id, |
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index b0b953683c1a..b330009fe42d 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c | |||
@@ -289,12 +289,11 @@ int affs_init_bitmap(struct super_block *sb, int *flags) | |||
289 | sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + | 289 | sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + |
290 | sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; | 290 | sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; |
291 | size = sbi->s_bmap_count * sizeof(*bm); | 291 | size = sbi->s_bmap_count * sizeof(*bm); |
292 | bm = sbi->s_bitmap = kmalloc(size, GFP_KERNEL); | 292 | bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL); |
293 | if (!sbi->s_bitmap) { | 293 | if (!sbi->s_bitmap) { |
294 | printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); | 294 | printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); |
295 | return -ENOMEM; | 295 | return -ENOMEM; |
296 | } | 296 | } |
297 | memset(sbi->s_bitmap, 0, size); | ||
298 | 297 | ||
299 | bmap_blk = (__be32 *)sbi->s_root_bh->b_data; | 298 | bmap_blk = (__be32 *)sbi->s_root_bh->b_data; |
300 | blk = sb->s_blocksize / 4 - 49; | 299 | blk = sb->s_blocksize / 4 - 49; |
diff --git a/fs/affs/dir.c b/fs/affs/dir.c index 5d9649fa1814..cad3ee340063 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c | |||
@@ -41,7 +41,7 @@ struct inode_operations affs_dir_inode_operations = { | |||
41 | static int | 41 | static int |
42 | affs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 42 | affs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
43 | { | 43 | { |
44 | struct inode *inode = filp->f_dentry->d_inode; | 44 | struct inode *inode = filp->f_path.dentry->d_inode; |
45 | struct super_block *sb = inode->i_sb; | 45 | struct super_block *sb = inode->i_sb; |
46 | struct buffer_head *dir_bh; | 46 | struct buffer_head *dir_bh; |
47 | struct buffer_head *fh_bh; | 47 | struct buffer_head *fh_bh; |
@@ -71,7 +71,7 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
71 | stored++; | 71 | stored++; |
72 | } | 72 | } |
73 | if (f_pos == 1) { | 73 | if (f_pos == 1) { |
74 | if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_dentry), DT_DIR) < 0) | 74 | if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_path.dentry), DT_DIR) < 0) |
75 | return stored; | 75 | return stored; |
76 | filp->f_pos = f_pos = 2; | 76 | filp->f_pos = f_pos = 2; |
77 | stored++; | 77 | stored++; |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 5ea72c3a16c3..3de93e799949 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -66,12 +66,12 @@ affs_write_super(struct super_block *sb) | |||
66 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); | 66 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); |
67 | } | 67 | } |
68 | 68 | ||
69 | static kmem_cache_t * affs_inode_cachep; | 69 | static struct kmem_cache * affs_inode_cachep; |
70 | 70 | ||
71 | static struct inode *affs_alloc_inode(struct super_block *sb) | 71 | static struct inode *affs_alloc_inode(struct super_block *sb) |
72 | { | 72 | { |
73 | struct affs_inode_info *ei; | 73 | struct affs_inode_info *ei; |
74 | ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, SLAB_KERNEL); | 74 | ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); |
75 | if (!ei) | 75 | if (!ei) |
76 | return NULL; | 76 | return NULL; |
77 | ei->vfs_inode.i_version = 1; | 77 | ei->vfs_inode.i_version = 1; |
@@ -83,7 +83,7 @@ static void affs_destroy_inode(struct inode *inode) | |||
83 | kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); | 83 | kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 86 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
87 | { | 87 | { |
88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; | 88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; |
89 | 89 | ||
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index a6ec75c56fcf..4acd04134055 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -392,10 +392,10 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir) | |||
392 | unsigned fpos; | 392 | unsigned fpos; |
393 | int ret; | 393 | int ret; |
394 | 394 | ||
395 | _enter("{%Ld,{%lu}}", file->f_pos, file->f_dentry->d_inode->i_ino); | 395 | _enter("{%Ld,{%lu}}", file->f_pos, file->f_path.dentry->d_inode->i_ino); |
396 | 396 | ||
397 | fpos = file->f_pos; | 397 | fpos = file->f_pos; |
398 | ret = afs_dir_iterate(file->f_dentry->d_inode, &fpos, cookie, filldir); | 398 | ret = afs_dir_iterate(file->f_path.dentry->d_inode, &fpos, cookie, filldir); |
399 | file->f_pos = fpos; | 399 | file->f_pos = fpos; |
400 | 400 | ||
401 | _leave(" = %d", ret); | 401 | _leave(" = %d", ret); |
diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c index f09a794f248e..615df2407cb2 100644 --- a/fs/afs/kafsasyncd.c +++ b/fs/afs/kafsasyncd.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/freezer.h> | ||
23 | #include "cell.h" | 24 | #include "cell.h" |
24 | #include "server.h" | 25 | #include "server.h" |
25 | #include "volume.h" | 26 | #include "volume.h" |
diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c index 65bc05ab8182..694344e4d3c7 100644 --- a/fs/afs/kafstimod.c +++ b/fs/afs/kafstimod.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/completion.h> | 15 | #include <linux/completion.h> |
16 | #include <linux/freezer.h> | ||
16 | #include "cell.h" | 17 | #include "cell.h" |
17 | #include "volume.h" | 18 | #include "volume.h" |
18 | #include "kafstimod.h" | 19 | #include "kafstimod.h" |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 99785a79d043..8f74e8450826 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <linux/namei.h> | 20 | #include <linux/namei.h> |
21 | #include <linux/namespace.h> | 21 | #include <linux/mnt_namespace.h> |
22 | #include "super.h" | 22 | #include "super.h" |
23 | #include "cell.h" | 23 | #include "cell.h" |
24 | #include "volume.h" | 24 | #include "volume.h" |
@@ -136,11 +136,11 @@ static int afs_mntpt_open(struct inode *inode, struct file *file) | |||
136 | { | 136 | { |
137 | kenter("%p,%p{%p{%s},%s}", | 137 | kenter("%p,%p{%p{%s},%s}", |
138 | inode, file, | 138 | inode, file, |
139 | file->f_dentry->d_parent, | 139 | file->f_path.dentry->d_parent, |
140 | file->f_dentry->d_parent ? | 140 | file->f_path.dentry->d_parent ? |
141 | file->f_dentry->d_parent->d_name.name : | 141 | file->f_path.dentry->d_parent->d_name.name : |
142 | (const unsigned char *) "", | 142 | (const unsigned char *) "", |
143 | file->f_dentry->d_name.name); | 143 | file->f_path.dentry->d_name.name); |
144 | 144 | ||
145 | return -EREMOTE; | 145 | return -EREMOTE; |
146 | } /* end afs_mntpt_open() */ | 146 | } /* end afs_mntpt_open() */ |
diff --git a/fs/afs/server.c b/fs/afs/server.c index 22afaae1a4ce..44aff81dc6a7 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -55,13 +55,12 @@ int afs_server_lookup(struct afs_cell *cell, const struct in_addr *addr, | |||
55 | _enter("%p,%08x,", cell, ntohl(addr->s_addr)); | 55 | _enter("%p,%08x,", cell, ntohl(addr->s_addr)); |
56 | 56 | ||
57 | /* allocate and initialise a server record */ | 57 | /* allocate and initialise a server record */ |
58 | server = kmalloc(sizeof(struct afs_server), GFP_KERNEL); | 58 | server = kzalloc(sizeof(struct afs_server), GFP_KERNEL); |
59 | if (!server) { | 59 | if (!server) { |
60 | _leave(" = -ENOMEM"); | 60 | _leave(" = -ENOMEM"); |
61 | return -ENOMEM; | 61 | return -ENOMEM; |
62 | } | 62 | } |
63 | 63 | ||
64 | memset(server, 0, sizeof(struct afs_server)); | ||
65 | atomic_set(&server->usage, 1); | 64 | atomic_set(&server->usage, 1); |
66 | 65 | ||
67 | INIT_LIST_HEAD(&server->link); | 66 | INIT_LIST_HEAD(&server->link); |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 67d1f5c819ec..18d9b77ba40f 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -35,7 +35,7 @@ struct afs_mount_params { | |||
35 | struct afs_volume *volume; | 35 | struct afs_volume *volume; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static void afs_i_init_once(void *foo, kmem_cache_t *cachep, | 38 | static void afs_i_init_once(void *foo, struct kmem_cache *cachep, |
39 | unsigned long flags); | 39 | unsigned long flags); |
40 | 40 | ||
41 | static int afs_get_sb(struct file_system_type *fs_type, | 41 | static int afs_get_sb(struct file_system_type *fs_type, |
@@ -65,7 +65,7 @@ static struct super_operations afs_super_ops = { | |||
65 | .put_super = afs_put_super, | 65 | .put_super = afs_put_super, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static kmem_cache_t *afs_inode_cachep; | 68 | static struct kmem_cache *afs_inode_cachep; |
69 | static atomic_t afs_count_active_inodes; | 69 | static atomic_t afs_count_active_inodes; |
70 | 70 | ||
71 | /*****************************************************************************/ | 71 | /*****************************************************************************/ |
@@ -242,14 +242,12 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) | |||
242 | kenter(""); | 242 | kenter(""); |
243 | 243 | ||
244 | /* allocate a superblock info record */ | 244 | /* allocate a superblock info record */ |
245 | as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL); | 245 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); |
246 | if (!as) { | 246 | if (!as) { |
247 | _leave(" = -ENOMEM"); | 247 | _leave(" = -ENOMEM"); |
248 | return -ENOMEM; | 248 | return -ENOMEM; |
249 | } | 249 | } |
250 | 250 | ||
251 | memset(as, 0, sizeof(struct afs_super_info)); | ||
252 | |||
253 | afs_get_volume(params->volume); | 251 | afs_get_volume(params->volume); |
254 | as->volume = params->volume; | 252 | as->volume = params->volume; |
255 | 253 | ||
@@ -384,7 +382,7 @@ static void afs_put_super(struct super_block *sb) | |||
384 | /* | 382 | /* |
385 | * initialise an inode cache slab element prior to any use | 383 | * initialise an inode cache slab element prior to any use |
386 | */ | 384 | */ |
387 | static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, | 385 | static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, |
388 | unsigned long flags) | 386 | unsigned long flags) |
389 | { | 387 | { |
390 | struct afs_vnode *vnode = (struct afs_vnode *) _vnode; | 388 | struct afs_vnode *vnode = (struct afs_vnode *) _vnode; |
@@ -412,7 +410,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb) | |||
412 | struct afs_vnode *vnode; | 410 | struct afs_vnode *vnode; |
413 | 411 | ||
414 | vnode = (struct afs_vnode *) | 412 | vnode = (struct afs_vnode *) |
415 | kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); | 413 | kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL); |
416 | if (!vnode) | 414 | if (!vnode) |
417 | return NULL; | 415 | return NULL; |
418 | 416 | ||
@@ -47,19 +47,19 @@ unsigned long aio_nr; /* current system wide number of aio requests */ | |||
47 | unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ | 47 | unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ |
48 | /*----end sysctl variables---*/ | 48 | /*----end sysctl variables---*/ |
49 | 49 | ||
50 | static kmem_cache_t *kiocb_cachep; | 50 | static struct kmem_cache *kiocb_cachep; |
51 | static kmem_cache_t *kioctx_cachep; | 51 | static struct kmem_cache *kioctx_cachep; |
52 | 52 | ||
53 | static struct workqueue_struct *aio_wq; | 53 | static struct workqueue_struct *aio_wq; |
54 | 54 | ||
55 | /* Used for rare fput completion. */ | 55 | /* Used for rare fput completion. */ |
56 | static void aio_fput_routine(void *); | 56 | static void aio_fput_routine(struct work_struct *); |
57 | static DECLARE_WORK(fput_work, aio_fput_routine, NULL); | 57 | static DECLARE_WORK(fput_work, aio_fput_routine); |
58 | 58 | ||
59 | static DEFINE_SPINLOCK(fput_lock); | 59 | static DEFINE_SPINLOCK(fput_lock); |
60 | static LIST_HEAD(fput_head); | 60 | static LIST_HEAD(fput_head); |
61 | 61 | ||
62 | static void aio_kick_handler(void *); | 62 | static void aio_kick_handler(struct work_struct *); |
63 | static void aio_queue_work(struct kioctx *); | 63 | static void aio_queue_work(struct kioctx *); |
64 | 64 | ||
65 | /* aio_setup | 65 | /* aio_setup |
@@ -227,7 +227,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
227 | 227 | ||
228 | INIT_LIST_HEAD(&ctx->active_reqs); | 228 | INIT_LIST_HEAD(&ctx->active_reqs); |
229 | INIT_LIST_HEAD(&ctx->run_list); | 229 | INIT_LIST_HEAD(&ctx->run_list); |
230 | INIT_WORK(&ctx->wq, aio_kick_handler, ctx); | 230 | INIT_DELAYED_WORK(&ctx->wq, aio_kick_handler); |
231 | 231 | ||
232 | if (aio_setup_ring(ctx) < 0) | 232 | if (aio_setup_ring(ctx) < 0) |
233 | goto out_freectx; | 233 | goto out_freectx; |
@@ -367,8 +367,7 @@ void fastcall __put_ioctx(struct kioctx *ctx) | |||
367 | { | 367 | { |
368 | unsigned nr_events = ctx->max_reqs; | 368 | unsigned nr_events = ctx->max_reqs; |
369 | 369 | ||
370 | if (unlikely(ctx->reqs_active)) | 370 | BUG_ON(ctx->reqs_active); |
371 | BUG(); | ||
372 | 371 | ||
373 | cancel_delayed_work(&ctx->wq); | 372 | cancel_delayed_work(&ctx->wq); |
374 | flush_workqueue(aio_wq); | 373 | flush_workqueue(aio_wq); |
@@ -470,7 +469,7 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
470 | wake_up(&ctx->wait); | 469 | wake_up(&ctx->wait); |
471 | } | 470 | } |
472 | 471 | ||
473 | static void aio_fput_routine(void *data) | 472 | static void aio_fput_routine(struct work_struct *data) |
474 | { | 473 | { |
475 | spin_lock_irq(&fput_lock); | 474 | spin_lock_irq(&fput_lock); |
476 | while (likely(!list_empty(&fput_head))) { | 475 | while (likely(!list_empty(&fput_head))) { |
@@ -505,8 +504,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
505 | assert_spin_locked(&ctx->ctx_lock); | 504 | assert_spin_locked(&ctx->ctx_lock); |
506 | 505 | ||
507 | req->ki_users --; | 506 | req->ki_users --; |
508 | if (unlikely(req->ki_users < 0)) | 507 | BUG_ON(req->ki_users < 0); |
509 | BUG(); | ||
510 | if (likely(req->ki_users)) | 508 | if (likely(req->ki_users)) |
511 | return 0; | 509 | return 0; |
512 | list_del(&req->ki_list); /* remove from active_reqs */ | 510 | list_del(&req->ki_list); /* remove from active_reqs */ |
@@ -588,7 +586,7 @@ static void use_mm(struct mm_struct *mm) | |||
588 | * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise | 586 | * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise |
589 | * it won't work. Update it accordingly if you change it here | 587 | * it won't work. Update it accordingly if you change it here |
590 | */ | 588 | */ |
591 | activate_mm(active_mm, mm); | 589 | switch_mm(active_mm, mm, tsk); |
592 | task_unlock(tsk); | 590 | task_unlock(tsk); |
593 | 591 | ||
594 | mmdrop(active_mm); | 592 | mmdrop(active_mm); |
@@ -601,9 +599,6 @@ static void use_mm(struct mm_struct *mm) | |||
601 | * by the calling kernel thread | 599 | * by the calling kernel thread |
602 | * (Note: this routine is intended to be called only | 600 | * (Note: this routine is intended to be called only |
603 | * from a kernel thread context) | 601 | * from a kernel thread context) |
604 | * | ||
605 | * Comments: Called with ctx->ctx_lock held. This nests | ||
606 | * task_lock instead ctx_lock. | ||
607 | */ | 602 | */ |
608 | static void unuse_mm(struct mm_struct *mm) | 603 | static void unuse_mm(struct mm_struct *mm) |
609 | { | 604 | { |
@@ -668,17 +663,6 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
668 | ssize_t (*retry)(struct kiocb *); | 663 | ssize_t (*retry)(struct kiocb *); |
669 | ssize_t ret; | 664 | ssize_t ret; |
670 | 665 | ||
671 | if (iocb->ki_retried++ > 1024*1024) { | ||
672 | printk("Maximal retry count. Bytes done %Zd\n", | ||
673 | iocb->ki_nbytes - iocb->ki_left); | ||
674 | return -EAGAIN; | ||
675 | } | ||
676 | |||
677 | if (!(iocb->ki_retried & 0xff)) { | ||
678 | pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried, | ||
679 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | ||
680 | } | ||
681 | |||
682 | if (!(retry = iocb->ki_retry)) { | 666 | if (!(retry = iocb->ki_retry)) { |
683 | printk("aio_run_iocb: iocb->ki_retry = NULL\n"); | 667 | printk("aio_run_iocb: iocb->ki_retry = NULL\n"); |
684 | return 0; | 668 | return 0; |
@@ -859,24 +843,26 @@ static inline void aio_run_all_iocbs(struct kioctx *ctx) | |||
859 | * space. | 843 | * space. |
860 | * Run on aiod's context. | 844 | * Run on aiod's context. |
861 | */ | 845 | */ |
862 | static void aio_kick_handler(void *data) | 846 | static void aio_kick_handler(struct work_struct *work) |
863 | { | 847 | { |
864 | struct kioctx *ctx = data; | 848 | struct kioctx *ctx = container_of(work, struct kioctx, wq.work); |
865 | mm_segment_t oldfs = get_fs(); | 849 | mm_segment_t oldfs = get_fs(); |
850 | struct mm_struct *mm; | ||
866 | int requeue; | 851 | int requeue; |
867 | 852 | ||
868 | set_fs(USER_DS); | 853 | set_fs(USER_DS); |
869 | use_mm(ctx->mm); | 854 | use_mm(ctx->mm); |
870 | spin_lock_irq(&ctx->ctx_lock); | 855 | spin_lock_irq(&ctx->ctx_lock); |
871 | requeue =__aio_run_iocbs(ctx); | 856 | requeue =__aio_run_iocbs(ctx); |
872 | unuse_mm(ctx->mm); | 857 | mm = ctx->mm; |
873 | spin_unlock_irq(&ctx->ctx_lock); | 858 | spin_unlock_irq(&ctx->ctx_lock); |
859 | unuse_mm(mm); | ||
874 | set_fs(oldfs); | 860 | set_fs(oldfs); |
875 | /* | 861 | /* |
876 | * we're in a worker thread already, don't use queue_delayed_work, | 862 | * we're in a worker thread already, don't use queue_delayed_work, |
877 | */ | 863 | */ |
878 | if (requeue) | 864 | if (requeue) |
879 | queue_work(aio_wq, &ctx->wq); | 865 | queue_delayed_work(aio_wq, &ctx->wq, 0); |
880 | } | 866 | } |
881 | 867 | ||
882 | 868 | ||
@@ -1007,9 +993,6 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) | |||
1007 | kunmap_atomic(ring, KM_IRQ1); | 993 | kunmap_atomic(ring, KM_IRQ1); |
1008 | 994 | ||
1009 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); | 995 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); |
1010 | |||
1011 | pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried, | ||
1012 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | ||
1013 | put_rq: | 996 | put_rq: |
1014 | /* everything turned out well, dispose of the aiocb. */ | 997 | /* everything turned out well, dispose of the aiocb. */ |
1015 | ret = __aio_put_req(ctx, iocb); | 998 | ret = __aio_put_req(ctx, iocb); |
@@ -1415,7 +1398,6 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb) | |||
1415 | kiocb->ki_iovec->iov_len = kiocb->ki_left; | 1398 | kiocb->ki_iovec->iov_len = kiocb->ki_left; |
1416 | kiocb->ki_nr_segs = 1; | 1399 | kiocb->ki_nr_segs = 1; |
1417 | kiocb->ki_cur_seg = 0; | 1400 | kiocb->ki_cur_seg = 0; |
1418 | kiocb->ki_nbytes = kiocb->ki_left; | ||
1419 | return 0; | 1401 | return 0; |
1420 | } | 1402 | } |
1421 | 1403 | ||
@@ -1593,7 +1575,6 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1593 | req->ki_opcode = iocb->aio_lio_opcode; | 1575 | req->ki_opcode = iocb->aio_lio_opcode; |
1594 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); | 1576 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); |
1595 | INIT_LIST_HEAD(&req->ki_wait.task_list); | 1577 | INIT_LIST_HEAD(&req->ki_wait.task_list); |
1596 | req->ki_retried = 0; | ||
1597 | 1578 | ||
1598 | ret = aio_setup_iocb(req); | 1579 | ret = aio_setup_iocb(req); |
1599 | 1580 | ||
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index 38ede5c9d6fd..f968d1342808 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c | |||
@@ -28,10 +28,11 @@ void autofs_kill_sb(struct super_block *sb) | |||
28 | /* | 28 | /* |
29 | * In the event of a failure in get_sb_nodev the superblock | 29 | * In the event of a failure in get_sb_nodev the superblock |
30 | * info is not present so nothing else has been setup, so | 30 | * info is not present so nothing else has been setup, so |
31 | * just exit when we are called from deactivate_super. | 31 | * just call kill_anon_super when we are called from |
32 | * deactivate_super. | ||
32 | */ | 33 | */ |
33 | if (!sbi) | 34 | if (!sbi) |
34 | return; | 35 | goto out_kill_sb; |
35 | 36 | ||
36 | if ( !sbi->catatonic ) | 37 | if ( !sbi->catatonic ) |
37 | autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ | 38 | autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ |
@@ -44,6 +45,7 @@ void autofs_kill_sb(struct super_block *sb) | |||
44 | 45 | ||
45 | kfree(sb->s_fs_info); | 46 | kfree(sb->s_fs_info); |
46 | 47 | ||
48 | out_kill_sb: | ||
47 | DPRINTK(("autofs: shutting down\n")); | 49 | DPRINTK(("autofs: shutting down\n")); |
48 | kill_anon_super(sb); | 50 | kill_anon_super(sb); |
49 | } | 51 | } |
@@ -209,7 +211,6 @@ fail_iput: | |||
209 | fail_free: | 211 | fail_free: |
210 | kfree(sbi); | 212 | kfree(sbi); |
211 | s->s_fs_info = NULL; | 213 | s->s_fs_info = NULL; |
212 | kill_anon_super(s); | ||
213 | fail_unlock: | 214 | fail_unlock: |
214 | return -EINVAL; | 215 | return -EINVAL; |
215 | } | 216 | } |
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 368a1c33a3c8..e698c51d2b02 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
@@ -45,7 +45,7 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi | |||
45 | struct autofs_dir_ent *ent = NULL; | 45 | struct autofs_dir_ent *ent = NULL; |
46 | struct autofs_dirhash *dirhash; | 46 | struct autofs_dirhash *dirhash; |
47 | struct autofs_sb_info *sbi; | 47 | struct autofs_sb_info *sbi; |
48 | struct inode * inode = filp->f_dentry->d_inode; | 48 | struct inode * inode = filp->f_path.dentry->d_inode; |
49 | off_t onr, nr; | 49 | off_t onr, nr; |
50 | 50 | ||
51 | lock_kernel(); | 51 | lock_kernel(); |
@@ -557,7 +557,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, | |||
557 | case AUTOFS_IOC_SETTIMEOUT: | 557 | case AUTOFS_IOC_SETTIMEOUT: |
558 | return autofs_get_set_timeout(sbi, argp); | 558 | return autofs_get_set_timeout(sbi, argp); |
559 | case AUTOFS_IOC_EXPIRE: | 559 | case AUTOFS_IOC_EXPIRE: |
560 | return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt, | 560 | return autofs_expire_run(inode->i_sb, sbi, filp->f_path.mnt, |
561 | argp); | 561 | argp); |
562 | default: | 562 | default: |
563 | return -ENOSYS; | 563 | return -ENOSYS; |
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index b13f32c8aeee..216b1a364ccb 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -150,7 +150,8 @@ static inline int autofs4_ispending(struct dentry *dentry) | |||
150 | 150 | ||
151 | static inline void autofs4_copy_atime(struct file *src, struct file *dst) | 151 | static inline void autofs4_copy_atime(struct file *src, struct file *dst) |
152 | { | 152 | { |
153 | dst->f_dentry->d_inode->i_atime = src->f_dentry->d_inode->i_atime; | 153 | dst->f_path.dentry->d_inode->i_atime = |
154 | src->f_path.dentry->d_inode->i_atime; | ||
154 | return; | 155 | return; |
155 | } | 156 | } |
156 | 157 | ||
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index ce7c0f1dd529..e8f6c5ad3e90 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -152,10 +152,11 @@ void autofs4_kill_sb(struct super_block *sb) | |||
152 | /* | 152 | /* |
153 | * In the event of a failure in get_sb_nodev the superblock | 153 | * In the event of a failure in get_sb_nodev the superblock |
154 | * info is not present so nothing else has been setup, so | 154 | * info is not present so nothing else has been setup, so |
155 | * just exit when we are called from deactivate_super. | 155 | * just call kill_anon_super when we are called from |
156 | * deactivate_super. | ||
156 | */ | 157 | */ |
157 | if (!sbi) | 158 | if (!sbi) |
158 | return; | 159 | goto out_kill_sb; |
159 | 160 | ||
160 | sb->s_fs_info = NULL; | 161 | sb->s_fs_info = NULL; |
161 | 162 | ||
@@ -167,6 +168,7 @@ void autofs4_kill_sb(struct super_block *sb) | |||
167 | 168 | ||
168 | kfree(sbi); | 169 | kfree(sbi); |
169 | 170 | ||
171 | out_kill_sb: | ||
170 | DPRINTK("shutting down"); | 172 | DPRINTK("shutting down"); |
171 | kill_anon_super(sb); | 173 | kill_anon_super(sb); |
172 | } | 174 | } |
@@ -311,7 +313,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
311 | struct autofs_sb_info *sbi; | 313 | struct autofs_sb_info *sbi; |
312 | struct autofs_info *ino; | 314 | struct autofs_info *ino; |
313 | 315 | ||
314 | sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL); | 316 | sbi = kmalloc(sizeof(*sbi), GFP_KERNEL); |
315 | if ( !sbi ) | 317 | if ( !sbi ) |
316 | goto fail_unlock; | 318 | goto fail_unlock; |
317 | DPRINTK("starting up, sbi = %p",sbi); | 319 | DPRINTK("starting up, sbi = %p",sbi); |
@@ -426,7 +428,6 @@ fail_ino: | |||
426 | fail_free: | 428 | fail_free: |
427 | kfree(sbi); | 429 | kfree(sbi); |
428 | s->s_fs_info = NULL; | 430 | s->s_fs_info = NULL; |
429 | kill_anon_super(s); | ||
430 | fail_unlock: | 431 | fail_unlock: |
431 | return -EINVAL; | 432 | return -EINVAL; |
432 | } | 433 | } |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index c1493524da4d..8d05b9f7578d 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -74,7 +74,7 @@ struct inode_operations autofs4_dir_inode_operations = { | |||
74 | static int autofs4_root_readdir(struct file *file, void *dirent, | 74 | static int autofs4_root_readdir(struct file *file, void *dirent, |
75 | filldir_t filldir) | 75 | filldir_t filldir) |
76 | { | 76 | { |
77 | struct autofs_sb_info *sbi = autofs4_sbi(file->f_dentry->d_sb); | 77 | struct autofs_sb_info *sbi = autofs4_sbi(file->f_path.dentry->d_sb); |
78 | int oz_mode = autofs4_oz_mode(sbi); | 78 | int oz_mode = autofs4_oz_mode(sbi); |
79 | 79 | ||
80 | DPRINTK("called, filp->f_pos = %lld", file->f_pos); | 80 | DPRINTK("called, filp->f_pos = %lld", file->f_pos); |
@@ -95,8 +95,8 @@ static int autofs4_root_readdir(struct file *file, void *dirent, | |||
95 | 95 | ||
96 | static int autofs4_dir_open(struct inode *inode, struct file *file) | 96 | static int autofs4_dir_open(struct inode *inode, struct file *file) |
97 | { | 97 | { |
98 | struct dentry *dentry = file->f_dentry; | 98 | struct dentry *dentry = file->f_path.dentry; |
99 | struct vfsmount *mnt = file->f_vfsmnt; | 99 | struct vfsmount *mnt = file->f_path.mnt; |
100 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 100 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
101 | struct dentry *cursor; | 101 | struct dentry *cursor; |
102 | int status; | 102 | int status; |
@@ -172,7 +172,7 @@ out: | |||
172 | 172 | ||
173 | static int autofs4_dir_close(struct inode *inode, struct file *file) | 173 | static int autofs4_dir_close(struct inode *inode, struct file *file) |
174 | { | 174 | { |
175 | struct dentry *dentry = file->f_dentry; | 175 | struct dentry *dentry = file->f_path.dentry; |
176 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 176 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
177 | struct dentry *cursor = file->private_data; | 177 | struct dentry *cursor = file->private_data; |
178 | int status = 0; | 178 | int status = 0; |
@@ -204,7 +204,7 @@ out: | |||
204 | 204 | ||
205 | static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir) | 205 | static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir) |
206 | { | 206 | { |
207 | struct dentry *dentry = file->f_dentry; | 207 | struct dentry *dentry = file->f_path.dentry; |
208 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 208 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
209 | struct dentry *cursor = file->private_data; | 209 | struct dentry *cursor = file->private_data; |
210 | int status; | 210 | int status; |
@@ -858,14 +858,14 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, | |||
858 | return autofs4_ask_reghost(sbi, p); | 858 | return autofs4_ask_reghost(sbi, p); |
859 | 859 | ||
860 | case AUTOFS_IOC_ASKUMOUNT: | 860 | case AUTOFS_IOC_ASKUMOUNT: |
861 | return autofs4_ask_umount(filp->f_vfsmnt, p); | 861 | return autofs4_ask_umount(filp->f_path.mnt, p); |
862 | 862 | ||
863 | /* return a single thing to expire */ | 863 | /* return a single thing to expire */ |
864 | case AUTOFS_IOC_EXPIRE: | 864 | case AUTOFS_IOC_EXPIRE: |
865 | return autofs4_expire_run(inode->i_sb,filp->f_vfsmnt,sbi, p); | 865 | return autofs4_expire_run(inode->i_sb,filp->f_path.mnt,sbi, p); |
866 | /* same as above, but can send multiple expires through pipe */ | 866 | /* same as above, but can send multiple expires through pipe */ |
867 | case AUTOFS_IOC_EXPIRE_MULTI: | 867 | case AUTOFS_IOC_EXPIRE_MULTI: |
868 | return autofs4_expire_multi(inode->i_sb,filp->f_vfsmnt,sbi, p); | 868 | return autofs4_expire_multi(inode->i_sb,filp->f_path.mnt,sbi, p); |
869 | 869 | ||
870 | default: | 870 | default: |
871 | return -ENOSYS; | 871 | return -ENOSYS; |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 34e6d7b220c3..869f5193ecc2 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -14,59 +14,307 @@ | |||
14 | #include <linux/time.h> | 14 | #include <linux/time.h> |
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
17 | #include <linux/poll.h> | ||
17 | 18 | ||
18 | static int return_EIO(void) | 19 | |
20 | static loff_t bad_file_llseek(struct file *file, loff_t offset, int origin) | ||
21 | { | ||
22 | return -EIO; | ||
23 | } | ||
24 | |||
25 | static ssize_t bad_file_read(struct file *filp, char __user *buf, | ||
26 | size_t size, loff_t *ppos) | ||
27 | { | ||
28 | return -EIO; | ||
29 | } | ||
30 | |||
31 | static ssize_t bad_file_write(struct file *filp, const char __user *buf, | ||
32 | size_t siz, loff_t *ppos) | ||
33 | { | ||
34 | return -EIO; | ||
35 | } | ||
36 | |||
37 | static ssize_t bad_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | ||
38 | unsigned long nr_segs, loff_t pos) | ||
39 | { | ||
40 | return -EIO; | ||
41 | } | ||
42 | |||
43 | static ssize_t bad_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
44 | unsigned long nr_segs, loff_t pos) | ||
45 | { | ||
46 | return -EIO; | ||
47 | } | ||
48 | |||
49 | static int bad_file_readdir(struct file *filp, void *dirent, filldir_t filldir) | ||
50 | { | ||
51 | return -EIO; | ||
52 | } | ||
53 | |||
54 | static unsigned int bad_file_poll(struct file *filp, poll_table *wait) | ||
55 | { | ||
56 | return POLLERR; | ||
57 | } | ||
58 | |||
59 | static int bad_file_ioctl (struct inode *inode, struct file *filp, | ||
60 | unsigned int cmd, unsigned long arg) | ||
61 | { | ||
62 | return -EIO; | ||
63 | } | ||
64 | |||
65 | static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd, | ||
66 | unsigned long arg) | ||
67 | { | ||
68 | return -EIO; | ||
69 | } | ||
70 | |||
71 | static long bad_file_compat_ioctl(struct file *file, unsigned int cmd, | ||
72 | unsigned long arg) | ||
73 | { | ||
74 | return -EIO; | ||
75 | } | ||
76 | |||
77 | static int bad_file_mmap(struct file *file, struct vm_area_struct *vma) | ||
78 | { | ||
79 | return -EIO; | ||
80 | } | ||
81 | |||
82 | static int bad_file_open(struct inode *inode, struct file *filp) | ||
83 | { | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
87 | static int bad_file_flush(struct file *file, fl_owner_t id) | ||
88 | { | ||
89 | return -EIO; | ||
90 | } | ||
91 | |||
92 | static int bad_file_release(struct inode *inode, struct file *filp) | ||
93 | { | ||
94 | return -EIO; | ||
95 | } | ||
96 | |||
97 | static int bad_file_fsync(struct file *file, struct dentry *dentry, | ||
98 | int datasync) | ||
99 | { | ||
100 | return -EIO; | ||
101 | } | ||
102 | |||
103 | static int bad_file_aio_fsync(struct kiocb *iocb, int datasync) | ||
104 | { | ||
105 | return -EIO; | ||
106 | } | ||
107 | |||
108 | static int bad_file_fasync(int fd, struct file *filp, int on) | ||
109 | { | ||
110 | return -EIO; | ||
111 | } | ||
112 | |||
113 | static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl) | ||
114 | { | ||
115 | return -EIO; | ||
116 | } | ||
117 | |||
118 | static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos, | ||
119 | size_t count, read_actor_t actor, void *target) | ||
120 | { | ||
121 | return -EIO; | ||
122 | } | ||
123 | |||
124 | static ssize_t bad_file_sendpage(struct file *file, struct page *page, | ||
125 | int off, size_t len, loff_t *pos, int more) | ||
126 | { | ||
127 | return -EIO; | ||
128 | } | ||
129 | |||
130 | static unsigned long bad_file_get_unmapped_area(struct file *file, | ||
131 | unsigned long addr, unsigned long len, | ||
132 | unsigned long pgoff, unsigned long flags) | ||
133 | { | ||
134 | return -EIO; | ||
135 | } | ||
136 | |||
137 | static int bad_file_check_flags(int flags) | ||
19 | { | 138 | { |
20 | return -EIO; | 139 | return -EIO; |
21 | } | 140 | } |
22 | 141 | ||
23 | #define EIO_ERROR ((void *) (return_EIO)) | 142 | static int bad_file_dir_notify(struct file *file, unsigned long arg) |
143 | { | ||
144 | return -EIO; | ||
145 | } | ||
146 | |||
147 | static int bad_file_flock(struct file *filp, int cmd, struct file_lock *fl) | ||
148 | { | ||
149 | return -EIO; | ||
150 | } | ||
151 | |||
152 | static ssize_t bad_file_splice_write(struct pipe_inode_info *pipe, | ||
153 | struct file *out, loff_t *ppos, size_t len, | ||
154 | unsigned int flags) | ||
155 | { | ||
156 | return -EIO; | ||
157 | } | ||
158 | |||
159 | static ssize_t bad_file_splice_read(struct file *in, loff_t *ppos, | ||
160 | struct pipe_inode_info *pipe, size_t len, | ||
161 | unsigned int flags) | ||
162 | { | ||
163 | return -EIO; | ||
164 | } | ||
24 | 165 | ||
25 | static const struct file_operations bad_file_ops = | 166 | static const struct file_operations bad_file_ops = |
26 | { | 167 | { |
27 | .llseek = EIO_ERROR, | 168 | .llseek = bad_file_llseek, |
28 | .aio_read = EIO_ERROR, | 169 | .read = bad_file_read, |
29 | .read = EIO_ERROR, | 170 | .write = bad_file_write, |
30 | .write = EIO_ERROR, | 171 | .aio_read = bad_file_aio_read, |
31 | .aio_write = EIO_ERROR, | 172 | .aio_write = bad_file_aio_write, |
32 | .readdir = EIO_ERROR, | 173 | .readdir = bad_file_readdir, |
33 | .poll = EIO_ERROR, | 174 | .poll = bad_file_poll, |
34 | .ioctl = EIO_ERROR, | 175 | .ioctl = bad_file_ioctl, |
35 | .mmap = EIO_ERROR, | 176 | .unlocked_ioctl = bad_file_unlocked_ioctl, |
36 | .open = EIO_ERROR, | 177 | .compat_ioctl = bad_file_compat_ioctl, |
37 | .flush = EIO_ERROR, | 178 | .mmap = bad_file_mmap, |
38 | .release = EIO_ERROR, | 179 | .open = bad_file_open, |
39 | .fsync = EIO_ERROR, | 180 | .flush = bad_file_flush, |
40 | .aio_fsync = EIO_ERROR, | 181 | .release = bad_file_release, |
41 | .fasync = EIO_ERROR, | 182 | .fsync = bad_file_fsync, |
42 | .lock = EIO_ERROR, | 183 | .aio_fsync = bad_file_aio_fsync, |
43 | .sendfile = EIO_ERROR, | 184 | .fasync = bad_file_fasync, |
44 | .sendpage = EIO_ERROR, | 185 | .lock = bad_file_lock, |
45 | .get_unmapped_area = EIO_ERROR, | 186 | .sendfile = bad_file_sendfile, |
187 | .sendpage = bad_file_sendpage, | ||
188 | .get_unmapped_area = bad_file_get_unmapped_area, | ||
189 | .check_flags = bad_file_check_flags, | ||
190 | .dir_notify = bad_file_dir_notify, | ||
191 | .flock = bad_file_flock, | ||
192 | .splice_write = bad_file_splice_write, | ||
193 | .splice_read = bad_file_splice_read, | ||
46 | }; | 194 | }; |
47 | 195 | ||
196 | static int bad_inode_create (struct inode *dir, struct dentry *dentry, | ||
197 | int mode, struct nameidata *nd) | ||
198 | { | ||
199 | return -EIO; | ||
200 | } | ||
201 | |||
202 | static struct dentry *bad_inode_lookup(struct inode *dir, | ||
203 | struct dentry *dentry, struct nameidata *nd) | ||
204 | { | ||
205 | return ERR_PTR(-EIO); | ||
206 | } | ||
207 | |||
208 | static int bad_inode_link (struct dentry *old_dentry, struct inode *dir, | ||
209 | struct dentry *dentry) | ||
210 | { | ||
211 | return -EIO; | ||
212 | } | ||
213 | |||
214 | static int bad_inode_unlink(struct inode *dir, struct dentry *dentry) | ||
215 | { | ||
216 | return -EIO; | ||
217 | } | ||
218 | |||
219 | static int bad_inode_symlink (struct inode *dir, struct dentry *dentry, | ||
220 | const char *symname) | ||
221 | { | ||
222 | return -EIO; | ||
223 | } | ||
224 | |||
225 | static int bad_inode_mkdir(struct inode *dir, struct dentry *dentry, | ||
226 | int mode) | ||
227 | { | ||
228 | return -EIO; | ||
229 | } | ||
230 | |||
231 | static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry) | ||
232 | { | ||
233 | return -EIO; | ||
234 | } | ||
235 | |||
236 | static int bad_inode_mknod (struct inode *dir, struct dentry *dentry, | ||
237 | int mode, dev_t rdev) | ||
238 | { | ||
239 | return -EIO; | ||
240 | } | ||
241 | |||
242 | static int bad_inode_rename (struct inode *old_dir, struct dentry *old_dentry, | ||
243 | struct inode *new_dir, struct dentry *new_dentry) | ||
244 | { | ||
245 | return -EIO; | ||
246 | } | ||
247 | |||
248 | static int bad_inode_readlink(struct dentry *dentry, char __user *buffer, | ||
249 | int buflen) | ||
250 | { | ||
251 | return -EIO; | ||
252 | } | ||
253 | |||
254 | static int bad_inode_permission(struct inode *inode, int mask, | ||
255 | struct nameidata *nd) | ||
256 | { | ||
257 | return -EIO; | ||
258 | } | ||
259 | |||
260 | static int bad_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
261 | struct kstat *stat) | ||
262 | { | ||
263 | return -EIO; | ||
264 | } | ||
265 | |||
266 | static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs) | ||
267 | { | ||
268 | return -EIO; | ||
269 | } | ||
270 | |||
271 | static int bad_inode_setxattr(struct dentry *dentry, const char *name, | ||
272 | const void *value, size_t size, int flags) | ||
273 | { | ||
274 | return -EIO; | ||
275 | } | ||
276 | |||
277 | static ssize_t bad_inode_getxattr(struct dentry *dentry, const char *name, | ||
278 | void *buffer, size_t size) | ||
279 | { | ||
280 | return -EIO; | ||
281 | } | ||
282 | |||
283 | static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer, | ||
284 | size_t buffer_size) | ||
285 | { | ||
286 | return -EIO; | ||
287 | } | ||
288 | |||
289 | static int bad_inode_removexattr(struct dentry *dentry, const char *name) | ||
290 | { | ||
291 | return -EIO; | ||
292 | } | ||
293 | |||
48 | static struct inode_operations bad_inode_ops = | 294 | static struct inode_operations bad_inode_ops = |
49 | { | 295 | { |
50 | .create = EIO_ERROR, | 296 | .create = bad_inode_create, |
51 | .lookup = EIO_ERROR, | 297 | .lookup = bad_inode_lookup, |
52 | .link = EIO_ERROR, | 298 | .link = bad_inode_link, |
53 | .unlink = EIO_ERROR, | 299 | .unlink = bad_inode_unlink, |
54 | .symlink = EIO_ERROR, | 300 | .symlink = bad_inode_symlink, |
55 | .mkdir = EIO_ERROR, | 301 | .mkdir = bad_inode_mkdir, |
56 | .rmdir = EIO_ERROR, | 302 | .rmdir = bad_inode_rmdir, |
57 | .mknod = EIO_ERROR, | 303 | .mknod = bad_inode_mknod, |
58 | .rename = EIO_ERROR, | 304 | .rename = bad_inode_rename, |
59 | .readlink = EIO_ERROR, | 305 | .readlink = bad_inode_readlink, |
60 | /* follow_link must be no-op, otherwise unmounting this inode | 306 | /* follow_link must be no-op, otherwise unmounting this inode |
61 | won't work */ | 307 | won't work */ |
62 | .truncate = EIO_ERROR, | 308 | /* put_link returns void */ |
63 | .permission = EIO_ERROR, | 309 | /* truncate returns void */ |
64 | .getattr = EIO_ERROR, | 310 | .permission = bad_inode_permission, |
65 | .setattr = EIO_ERROR, | 311 | .getattr = bad_inode_getattr, |
66 | .setxattr = EIO_ERROR, | 312 | .setattr = bad_inode_setattr, |
67 | .getxattr = EIO_ERROR, | 313 | .setxattr = bad_inode_setxattr, |
68 | .listxattr = EIO_ERROR, | 314 | .getxattr = bad_inode_getxattr, |
69 | .removexattr = EIO_ERROR, | 315 | .listxattr = bad_inode_listxattr, |
316 | .removexattr = bad_inode_removexattr, | ||
317 | /* truncate_range returns void */ | ||
70 | }; | 318 | }; |
71 | 319 | ||
72 | 320 | ||
@@ -88,7 +336,7 @@ static struct inode_operations bad_inode_ops = | |||
88 | * on it to fail from this point on. | 336 | * on it to fail from this point on. |
89 | */ | 337 | */ |
90 | 338 | ||
91 | void make_bad_inode(struct inode * inode) | 339 | void make_bad_inode(struct inode *inode) |
92 | { | 340 | { |
93 | remove_inode_hash(inode); | 341 | remove_inode_hash(inode); |
94 | 342 | ||
@@ -113,7 +361,7 @@ EXPORT_SYMBOL(make_bad_inode); | |||
113 | * Returns true if the inode in question has been marked as bad. | 361 | * Returns true if the inode in question has been marked as bad. |
114 | */ | 362 | */ |
115 | 363 | ||
116 | int is_bad_inode(struct inode * inode) | 364 | int is_bad_inode(struct inode *inode) |
117 | { | 365 | { |
118 | return (inode->i_op == &bad_inode_ops); | 366 | return (inode->i_op == &bad_inode_ops); |
119 | } | 367 | } |
diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 81b042ee24e6..af5bb93276f8 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c | |||
@@ -260,7 +260,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds, | |||
260 | goto error; | 260 | goto error; |
261 | } | 261 | } |
262 | 262 | ||
263 | this_node = (befs_btree_node *) kmalloc(sizeof (befs_btree_node), | 263 | this_node = kmalloc(sizeof (befs_btree_node), |
264 | GFP_NOFS); | 264 | GFP_NOFS); |
265 | if (!this_node) { | 265 | if (!this_node) { |
266 | befs_error(sb, "befs_btree_find() failed to allocate %u " | 266 | befs_error(sb, "befs_btree_find() failed to allocate %u " |
diff --git a/fs/befs/debug.c b/fs/befs/debug.c index e831a8f30849..b8e304a0661e 100644 --- a/fs/befs/debug.c +++ b/fs/befs/debug.c | |||
@@ -28,7 +28,7 @@ void | |||
28 | befs_error(const struct super_block *sb, const char *fmt, ...) | 28 | befs_error(const struct super_block *sb, const char *fmt, ...) |
29 | { | 29 | { |
30 | va_list args; | 30 | va_list args; |
31 | char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL); | 31 | char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL); |
32 | if (err_buf == NULL) { | 32 | if (err_buf == NULL) { |
33 | printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE); | 33 | printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE); |
34 | return; | 34 | return; |
@@ -46,7 +46,7 @@ void | |||
46 | befs_warning(const struct super_block *sb, const char *fmt, ...) | 46 | befs_warning(const struct super_block *sb, const char *fmt, ...) |
47 | { | 47 | { |
48 | va_list args; | 48 | va_list args; |
49 | char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL); | 49 | char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL); |
50 | if (err_buf == NULL) { | 50 | if (err_buf == NULL) { |
51 | printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE); | 51 | printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE); |
52 | return; | 52 | return; |
@@ -70,7 +70,7 @@ befs_debug(const struct super_block *sb, const char *fmt, ...) | |||
70 | char *err_buf = NULL; | 70 | char *err_buf = NULL; |
71 | 71 | ||
72 | if (BEFS_SB(sb)->mount_opts.debug) { | 72 | if (BEFS_SB(sb)->mount_opts.debug) { |
73 | err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL); | 73 | err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL); |
74 | if (err_buf == NULL) { | 74 | if (err_buf == NULL) { |
75 | printk(KERN_ERR "could not allocate %d bytes\n", | 75 | printk(KERN_ERR "could not allocate %d bytes\n", |
76 | ERRBUFSIZE); | 76 | ERRBUFSIZE); |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 07f7144f0e2e..481e59b9d91c 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -61,7 +61,7 @@ static const struct super_operations befs_sops = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* slab cache for befs_inode_info objects */ | 63 | /* slab cache for befs_inode_info objects */ |
64 | static kmem_cache_t *befs_inode_cachep; | 64 | static struct kmem_cache *befs_inode_cachep; |
65 | 65 | ||
66 | static const struct file_operations befs_dir_operations = { | 66 | static const struct file_operations befs_dir_operations = { |
67 | .read = generic_read_dir, | 67 | .read = generic_read_dir, |
@@ -212,7 +212,7 @@ befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
212 | static int | 212 | static int |
213 | befs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 213 | befs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
214 | { | 214 | { |
215 | struct inode *inode = filp->f_dentry->d_inode; | 215 | struct inode *inode = filp->f_path.dentry->d_inode; |
216 | struct super_block *sb = inode->i_sb; | 216 | struct super_block *sb = inode->i_sb; |
217 | befs_data_stream *ds = &BEFS_I(inode)->i_data.ds; | 217 | befs_data_stream *ds = &BEFS_I(inode)->i_data.ds; |
218 | befs_off_t value; | 218 | befs_off_t value; |
@@ -222,7 +222,7 @@ befs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
222 | char keybuf[BEFS_NAME_LEN + 1]; | 222 | char keybuf[BEFS_NAME_LEN + 1]; |
223 | char *nlsname; | 223 | char *nlsname; |
224 | int nlsnamelen; | 224 | int nlsnamelen; |
225 | const char *dirname = filp->f_dentry->d_name.name; | 225 | const char *dirname = filp->f_path.dentry->d_name.name; |
226 | 226 | ||
227 | befs_debug(sb, "---> befs_readdir() " | 227 | befs_debug(sb, "---> befs_readdir() " |
228 | "name %s, inode %ld, filp->f_pos %Ld", | 228 | "name %s, inode %ld, filp->f_pos %Ld", |
@@ -277,7 +277,7 @@ befs_alloc_inode(struct super_block *sb) | |||
277 | { | 277 | { |
278 | struct befs_inode_info *bi; | 278 | struct befs_inode_info *bi; |
279 | bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, | 279 | bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, |
280 | SLAB_KERNEL); | 280 | GFP_KERNEL); |
281 | if (!bi) | 281 | if (!bi) |
282 | return NULL; | 282 | return NULL; |
283 | return &bi->vfs_inode; | 283 | return &bi->vfs_inode; |
@@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode) | |||
289 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); | 289 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); |
290 | } | 290 | } |
291 | 291 | ||
292 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 292 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
293 | { | 293 | { |
294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; | 294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; |
295 | 295 | ||
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index a650f1d0b85e..2a746e688df5 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -27,7 +27,7 @@ static struct buffer_head * bfs_find_entry(struct inode * dir, | |||
27 | 27 | ||
28 | static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) | 28 | static int bfs_readdir(struct file * f, void * dirent, filldir_t filldir) |
29 | { | 29 | { |
30 | struct inode * dir = f->f_dentry->d_inode; | 30 | struct inode * dir = f->f_path.dentry->d_inode; |
31 | struct buffer_head * bh; | 31 | struct buffer_head * bh; |
32 | struct bfs_dirent * de; | 32 | struct bfs_dirent * de; |
33 | unsigned int offset; | 33 | unsigned int offset; |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index ed27ffb3459e..134c99941a63 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/bfs/inode.c | 2 | * fs/bfs/inode.c |
3 | * BFS superblock and inode operations. | 3 | * BFS superblock and inode operations. |
4 | * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com> | 4 | * Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> |
5 | * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. | 5 | * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds. |
6 | * | 6 | * |
7 | * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005. | 7 | * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005. |
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
19 | #include "bfs.h" | 19 | #include "bfs.h" |
20 | 20 | ||
21 | MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>"); | 21 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); |
22 | MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux"); | 22 | MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux"); |
23 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
24 | 24 | ||
@@ -228,12 +228,12 @@ static void bfs_write_super(struct super_block *s) | |||
228 | unlock_kernel(); | 228 | unlock_kernel(); |
229 | } | 229 | } |
230 | 230 | ||
231 | static kmem_cache_t * bfs_inode_cachep; | 231 | static struct kmem_cache * bfs_inode_cachep; |
232 | 232 | ||
233 | static struct inode *bfs_alloc_inode(struct super_block *sb) | 233 | static struct inode *bfs_alloc_inode(struct super_block *sb) |
234 | { | 234 | { |
235 | struct bfs_inode_info *bi; | 235 | struct bfs_inode_info *bi; |
236 | bi = kmem_cache_alloc(bfs_inode_cachep, SLAB_KERNEL); | 236 | bi = kmem_cache_alloc(bfs_inode_cachep, GFP_KERNEL); |
237 | if (!bi) | 237 | if (!bi) |
238 | return NULL; | 238 | return NULL; |
239 | return &bi->vfs_inode; | 239 | return &bi->vfs_inode; |
@@ -244,7 +244,7 @@ static void bfs_destroy_inode(struct inode *inode) | |||
244 | kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); | 244 | kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); |
245 | } | 245 | } |
246 | 246 | ||
247 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 247 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
248 | { | 248 | { |
249 | struct bfs_inode_info *bi = foo; | 249 | struct bfs_inode_info *bi = foo; |
250 | 250 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 517e111bb7ef..813a887cd2b3 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -274,7 +274,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
274 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && | 274 | if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && |
275 | N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || | 275 | N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || |
276 | N_TRSIZE(ex) || N_DRSIZE(ex) || | 276 | N_TRSIZE(ex) || N_DRSIZE(ex) || |
277 | i_size_read(bprm->file->f_dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { | 277 | i_size_read(bprm->file->f_path.dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { |
278 | return -ENOEXEC; | 278 | return -ENOEXEC; |
279 | } | 279 | } |
280 | 280 | ||
@@ -389,7 +389,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
389 | { | 389 | { |
390 | printk(KERN_WARNING | 390 | printk(KERN_WARNING |
391 | "fd_offset is not page aligned. Please convert program: %s\n", | 391 | "fd_offset is not page aligned. Please convert program: %s\n", |
392 | bprm->file->f_dentry->d_name.name); | 392 | bprm->file->f_path.dentry->d_name.name); |
393 | error_time = jiffies; | 393 | error_time = jiffies; |
394 | } | 394 | } |
395 | 395 | ||
@@ -469,7 +469,7 @@ static int load_aout_library(struct file *file) | |||
469 | int retval; | 469 | int retval; |
470 | struct exec ex; | 470 | struct exec ex; |
471 | 471 | ||
472 | inode = file->f_dentry->d_inode; | 472 | inode = file->f_path.dentry->d_inode; |
473 | 473 | ||
474 | retval = -ENOEXEC; | 474 | retval = -ENOEXEC; |
475 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); | 475 | error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); |
@@ -506,7 +506,7 @@ static int load_aout_library(struct file *file) | |||
506 | { | 506 | { |
507 | printk(KERN_WARNING | 507 | printk(KERN_WARNING |
508 | "N_TXTOFF is not page aligned. Please convert library: %s\n", | 508 | "N_TXTOFF is not page aligned. Please convert library: %s\n", |
509 | file->f_dentry->d_name.name); | 509 | file->f_path.dentry->d_name.name); |
510 | error_time = jiffies; | 510 | error_time = jiffies; |
511 | } | 511 | } |
512 | down_write(¤t->mm->mmap_sem); | 512 | down_write(¤t->mm->mmap_sem); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 79b05a1a4365..7cb28720f90e 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -47,10 +47,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | |||
47 | static int load_elf_library(struct file *); | 47 | static int load_elf_library(struct file *); |
48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); | 48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
49 | 49 | ||
50 | #ifndef elf_addr_t | ||
51 | #define elf_addr_t unsigned long | ||
52 | #endif | ||
53 | |||
54 | /* | 50 | /* |
55 | * If we don't support core dumping, then supply a NULL so we | 51 | * If we don't support core dumping, then supply a NULL so we |
56 | * don't even try. | 52 | * don't even try. |
@@ -243,8 +239,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
243 | if (interp_aout) { | 239 | if (interp_aout) { |
244 | argv = sp + 2; | 240 | argv = sp + 2; |
245 | envp = argv + argc + 1; | 241 | envp = argv + argc + 1; |
246 | __put_user((elf_addr_t)(unsigned long)argv, sp++); | 242 | if (__put_user((elf_addr_t)(unsigned long)argv, sp++) || |
247 | __put_user((elf_addr_t)(unsigned long)envp, sp++); | 243 | __put_user((elf_addr_t)(unsigned long)envp, sp++)) |
244 | return -EFAULT; | ||
248 | } else { | 245 | } else { |
249 | argv = sp; | 246 | argv = sp; |
250 | envp = argv + argc + 1; | 247 | envp = argv + argc + 1; |
@@ -254,7 +251,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
254 | p = current->mm->arg_end = current->mm->arg_start; | 251 | p = current->mm->arg_end = current->mm->arg_start; |
255 | while (argc-- > 0) { | 252 | while (argc-- > 0) { |
256 | size_t len; | 253 | size_t len; |
257 | __put_user((elf_addr_t)p, argv++); | 254 | if (__put_user((elf_addr_t)p, argv++)) |
255 | return -EFAULT; | ||
258 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 256 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
259 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 257 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
260 | return 0; | 258 | return 0; |
@@ -265,7 +263,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
265 | current->mm->arg_end = current->mm->env_start = p; | 263 | current->mm->arg_end = current->mm->env_start = p; |
266 | while (envc-- > 0) { | 264 | while (envc-- > 0) { |
267 | size_t len; | 265 | size_t len; |
268 | __put_user((elf_addr_t)p, envp++); | 266 | if (__put_user((elf_addr_t)p, envp++)) |
267 | return -EFAULT; | ||
269 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 268 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
270 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 269 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
271 | return 0; | 270 | return 0; |
@@ -545,7 +544,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
545 | unsigned long reloc_func_desc = 0; | 544 | unsigned long reloc_func_desc = 0; |
546 | char passed_fileno[6]; | 545 | char passed_fileno[6]; |
547 | struct files_struct *files; | 546 | struct files_struct *files; |
548 | int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT; | 547 | int executable_stack = EXSTACK_DEFAULT; |
549 | unsigned long def_flags = 0; | 548 | unsigned long def_flags = 0; |
550 | struct { | 549 | struct { |
551 | struct elfhdr elf_ex; | 550 | struct elfhdr elf_ex; |
@@ -708,7 +707,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
708 | executable_stack = EXSTACK_DISABLE_X; | 707 | executable_stack = EXSTACK_DISABLE_X; |
709 | break; | 708 | break; |
710 | } | 709 | } |
711 | have_pt_gnu_stack = (i < loc->elf_ex.e_phnum); | ||
712 | 710 | ||
713 | /* Some simple consistency checks for the interpreter */ | 711 | /* Some simple consistency checks for the interpreter */ |
714 | if (elf_interpreter) { | 712 | if (elf_interpreter) { |
@@ -1186,7 +1184,7 @@ static int maydump(struct vm_area_struct *vma) | |||
1186 | 1184 | ||
1187 | /* Dump shared memory only if mapped from an anonymous file. */ | 1185 | /* Dump shared memory only if mapped from an anonymous file. */ |
1188 | if (vma->vm_flags & VM_SHARED) | 1186 | if (vma->vm_flags & VM_SHARED) |
1189 | return vma->vm_file->f_dentry->d_inode->i_nlink == 0; | 1187 | return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0; |
1190 | 1188 | ||
1191 | /* If it hasn't been written to, don't write it out */ | 1189 | /* If it hasn't been written to, don't write it out */ |
1192 | if (!vma->anon_vma) | 1190 | if (!vma->anon_vma) |
@@ -1313,7 +1311,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1313 | prstatus->pr_pid = p->pid; | 1311 | prstatus->pr_pid = p->pid; |
1314 | prstatus->pr_ppid = p->parent->pid; | 1312 | prstatus->pr_ppid = p->parent->pid; |
1315 | prstatus->pr_pgrp = process_group(p); | 1313 | prstatus->pr_pgrp = process_group(p); |
1316 | prstatus->pr_sid = p->signal->session; | 1314 | prstatus->pr_sid = process_session(p); |
1317 | if (thread_group_leader(p)) { | 1315 | if (thread_group_leader(p)) { |
1318 | /* | 1316 | /* |
1319 | * This is the record for the group leader. Add in the | 1317 | * This is the record for the group leader. Add in the |
@@ -1359,7 +1357,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1359 | psinfo->pr_pid = p->pid; | 1357 | psinfo->pr_pid = p->pid; |
1360 | psinfo->pr_ppid = p->parent->pid; | 1358 | psinfo->pr_ppid = p->parent->pid; |
1361 | psinfo->pr_pgrp = process_group(p); | 1359 | psinfo->pr_pgrp = process_group(p); |
1362 | psinfo->pr_sid = p->signal->session; | 1360 | psinfo->pr_sid = process_session(p); |
1363 | 1361 | ||
1364 | i = p->state ? ffz(~p->state) + 1 : 0; | 1362 | i = p->state ? ffz(~p->state) + 1 : 0; |
1365 | psinfo->pr_state = i; | 1363 | psinfo->pr_state = i; |
@@ -1582,6 +1580,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1582 | 1580 | ||
1583 | sz += thread_status_size; | 1581 | sz += thread_status_size; |
1584 | 1582 | ||
1583 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1584 | sz += ELF_CORE_EXTRA_NOTES_SIZE; | ||
1585 | #endif | ||
1586 | |||
1585 | fill_elf_note_phdr(&phdr, sz, offset); | 1587 | fill_elf_note_phdr(&phdr, sz, offset); |
1586 | offset += sz; | 1588 | offset += sz; |
1587 | DUMP_WRITE(&phdr, sizeof(phdr)); | 1589 | DUMP_WRITE(&phdr, sizeof(phdr)); |
@@ -1622,6 +1624,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1622 | if (!writenote(notes + i, file, &foffset)) | 1624 | if (!writenote(notes + i, file, &foffset)) |
1623 | goto end_coredump; | 1625 | goto end_coredump; |
1624 | 1626 | ||
1627 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1628 | ELF_CORE_WRITE_EXTRA_NOTES; | ||
1629 | #endif | ||
1630 | |||
1625 | /* write out the thread status notes section */ | 1631 | /* write out the thread status notes section */ |
1626 | list_for_each(t, &thread_list) { | 1632 | list_for_each(t, &thread_list) { |
1627 | struct elf_thread_status *tmp = | 1633 | struct elf_thread_status *tmp = |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index f86d5c9ce5eb..6e6d4568d548 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -40,9 +40,6 @@ | |||
40 | #include <asm/pgalloc.h> | 40 | #include <asm/pgalloc.h> |
41 | 41 | ||
42 | typedef char *elf_caddr_t; | 42 | typedef char *elf_caddr_t; |
43 | #ifndef elf_addr_t | ||
44 | #define elf_addr_t unsigned long | ||
45 | #endif | ||
46 | 43 | ||
47 | #if 0 | 44 | #if 0 |
48 | #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ ) | 45 | #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ ) |
@@ -709,12 +706,11 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, | |||
709 | return -ELIBBAD; | 706 | return -ELIBBAD; |
710 | 707 | ||
711 | size = sizeof(*loadmap) + nloads * sizeof(*seg); | 708 | size = sizeof(*loadmap) + nloads * sizeof(*seg); |
712 | loadmap = kmalloc(size, GFP_KERNEL); | 709 | loadmap = kzalloc(size, GFP_KERNEL); |
713 | if (!loadmap) | 710 | if (!loadmap) |
714 | return -ENOMEM; | 711 | return -ENOMEM; |
715 | 712 | ||
716 | params->loadmap = loadmap; | 713 | params->loadmap = loadmap; |
717 | memset(loadmap, 0, size); | ||
718 | 714 | ||
719 | loadmap->version = ELF32_FDPIC_LOADMAP_VERSION; | 715 | loadmap->version = ELF32_FDPIC_LOADMAP_VERSION; |
720 | loadmap->nsegs = nloads; | 716 | loadmap->nsegs = nloads; |
@@ -858,7 +854,7 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, | |||
858 | 854 | ||
859 | dynamic_error: | 855 | dynamic_error: |
860 | printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n", | 856 | printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n", |
861 | what, file->f_dentry->d_inode->i_ino); | 857 | what, file->f_path.dentry->d_inode->i_ino); |
862 | return -ELIBBAD; | 858 | return -ELIBBAD; |
863 | } | 859 | } |
864 | 860 | ||
@@ -1189,7 +1185,7 @@ static int maydump(struct vm_area_struct *vma) | |||
1189 | 1185 | ||
1190 | /* Dump shared memory only if mapped from an anonymous file. */ | 1186 | /* Dump shared memory only if mapped from an anonymous file. */ |
1191 | if (vma->vm_flags & VM_SHARED) { | 1187 | if (vma->vm_flags & VM_SHARED) { |
1192 | if (vma->vm_file->f_dentry->d_inode->i_nlink == 0) { | 1188 | if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0) { |
1193 | kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags); | 1189 | kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags); |
1194 | return 1; | 1190 | return 1; |
1195 | } | 1191 | } |
@@ -1325,7 +1321,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1325 | prstatus->pr_pid = p->pid; | 1321 | prstatus->pr_pid = p->pid; |
1326 | prstatus->pr_ppid = p->parent->pid; | 1322 | prstatus->pr_ppid = p->parent->pid; |
1327 | prstatus->pr_pgrp = process_group(p); | 1323 | prstatus->pr_pgrp = process_group(p); |
1328 | prstatus->pr_sid = p->signal->session; | 1324 | prstatus->pr_sid = process_session(p); |
1329 | if (thread_group_leader(p)) { | 1325 | if (thread_group_leader(p)) { |
1330 | /* | 1326 | /* |
1331 | * This is the record for the group leader. Add in the | 1327 | * This is the record for the group leader. Add in the |
@@ -1374,7 +1370,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1374 | psinfo->pr_pid = p->pid; | 1370 | psinfo->pr_pid = p->pid; |
1375 | psinfo->pr_ppid = p->parent->pid; | 1371 | psinfo->pr_ppid = p->parent->pid; |
1376 | psinfo->pr_pgrp = process_group(p); | 1372 | psinfo->pr_pgrp = process_group(p); |
1377 | psinfo->pr_sid = p->signal->session; | 1373 | psinfo->pr_sid = process_session(p); |
1378 | 1374 | ||
1379 | i = p->state ? ffz(~p->state) + 1 : 0; | 1375 | i = p->state ? ffz(~p->state) + 1 : 0; |
1380 | psinfo->pr_state = i; | 1376 | psinfo->pr_state = i; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index a62fd4018a20..ae8595d49856 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -429,7 +429,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
429 | int ret; | 429 | int ret; |
430 | 430 | ||
431 | hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ | 431 | hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ |
432 | inode = bprm->file->f_dentry->d_inode; | 432 | inode = bprm->file->f_path.dentry->d_inode; |
433 | 433 | ||
434 | text_len = ntohl(hdr->data_start); | 434 | text_len = ntohl(hdr->data_start); |
435 | data_len = ntohl(hdr->data_end) - ntohl(hdr->data_start); | 435 | data_len = ntohl(hdr->data_end) - ntohl(hdr->data_start); |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 1713c48fef54..c2e08252af35 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -311,7 +311,7 @@ static Node *create_entry(const char __user *buffer, size_t count) | |||
311 | 311 | ||
312 | err = -ENOMEM; | 312 | err = -ENOMEM; |
313 | memsize = sizeof(Node) + count + 8; | 313 | memsize = sizeof(Node) + count + 8; |
314 | e = (Node *) kmalloc(memsize, GFP_USER); | 314 | e = kmalloc(memsize, GFP_USER); |
315 | if (!e) | 315 | if (!e) |
316 | goto out; | 316 | goto out; |
317 | 317 | ||
@@ -542,7 +542,7 @@ static void kill_node(Node *e) | |||
542 | static ssize_t | 542 | static ssize_t |
543 | bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) | 543 | bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos) |
544 | { | 544 | { |
545 | Node *e = file->f_dentry->d_inode->i_private; | 545 | Node *e = file->f_path.dentry->d_inode->i_private; |
546 | loff_t pos = *ppos; | 546 | loff_t pos = *ppos; |
547 | ssize_t res; | 547 | ssize_t res; |
548 | char *page; | 548 | char *page; |
@@ -576,7 +576,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, | |||
576 | size_t count, loff_t *ppos) | 576 | size_t count, loff_t *ppos) |
577 | { | 577 | { |
578 | struct dentry *root; | 578 | struct dentry *root; |
579 | Node *e = file->f_dentry->d_inode->i_private; | 579 | Node *e = file->f_path.dentry->d_inode->i_private; |
580 | int res = parse_command(buffer, count); | 580 | int res = parse_command(buffer, count); |
581 | 581 | ||
582 | switch (res) { | 582 | switch (res) { |
@@ -584,7 +584,7 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer, | |||
584 | break; | 584 | break; |
585 | case 2: set_bit(Enabled, &e->flags); | 585 | case 2: set_bit(Enabled, &e->flags); |
586 | break; | 586 | break; |
587 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); | 587 | case 3: root = dget(file->f_path.mnt->mnt_sb->s_root); |
588 | mutex_lock(&root->d_inode->i_mutex); | 588 | mutex_lock(&root->d_inode->i_mutex); |
589 | 589 | ||
590 | kill_node(e); | 590 | kill_node(e); |
@@ -610,7 +610,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer, | |||
610 | Node *e; | 610 | Node *e; |
611 | struct inode *inode; | 611 | struct inode *inode; |
612 | struct dentry *root, *dentry; | 612 | struct dentry *root, *dentry; |
613 | struct super_block *sb = file->f_vfsmnt->mnt_sb; | 613 | struct super_block *sb = file->f_path.mnt->mnt_sb; |
614 | int err = 0; | 614 | int err = 0; |
615 | 615 | ||
616 | e = create_entry(buffer, count); | 616 | e = create_entry(buffer, count); |
@@ -699,7 +699,7 @@ static ssize_t bm_status_write(struct file * file, const char __user * buffer, | |||
699 | switch (res) { | 699 | switch (res) { |
700 | case 1: enabled = 0; break; | 700 | case 1: enabled = 0; break; |
701 | case 2: enabled = 1; break; | 701 | case 2: enabled = 1; break; |
702 | case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root); | 702 | case 3: root = dget(file->f_path.mnt->mnt_sb->s_root); |
703 | mutex_lock(&root->d_inode->i_mutex); | 703 | mutex_lock(&root->d_inode->i_mutex); |
704 | 704 | ||
705 | while (!list_empty(&entries)) | 705 | while (!list_empty(&entries)) |
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #define BIO_POOL_SIZE 256 | 31 | #define BIO_POOL_SIZE 256 |
32 | 32 | ||
33 | static kmem_cache_t *bio_slab __read_mostly; | 33 | static struct kmem_cache *bio_slab __read_mostly; |
34 | 34 | ||
35 | #define BIOVEC_NR_POOLS 6 | 35 | #define BIOVEC_NR_POOLS 6 |
36 | 36 | ||
@@ -44,7 +44,7 @@ mempool_t *bio_split_pool __read_mostly; | |||
44 | struct biovec_slab { | 44 | struct biovec_slab { |
45 | int nr_vecs; | 45 | int nr_vecs; |
46 | char *name; | 46 | char *name; |
47 | kmem_cache_t *slab; | 47 | struct kmem_cache *slab; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | 50 | /* |
@@ -560,10 +560,8 @@ struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr, | |||
560 | break; | 560 | break; |
561 | } | 561 | } |
562 | 562 | ||
563 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) { | 563 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) |
564 | ret = -EINVAL; | ||
565 | break; | 564 | break; |
566 | } | ||
567 | 565 | ||
568 | len -= bytes; | 566 | len -= bytes; |
569 | } | 567 | } |
@@ -622,10 +620,9 @@ static struct bio *__bio_map_user_iov(request_queue_t *q, | |||
622 | 620 | ||
623 | nr_pages += end - start; | 621 | nr_pages += end - start; |
624 | /* | 622 | /* |
625 | * transfer and buffer must be aligned to at least hardsector | 623 | * buffer must be aligned to at least hardsector size for now |
626 | * size for now, in the future we can relax this restriction | ||
627 | */ | 624 | */ |
628 | if ((uaddr & queue_dma_alignment(q)) || (len & queue_dma_alignment(q))) | 625 | if (uaddr & queue_dma_alignment(q)) |
629 | return ERR_PTR(-EINVAL); | 626 | return ERR_PTR(-EINVAL); |
630 | } | 627 | } |
631 | 628 | ||
@@ -751,7 +748,6 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, | |||
751 | int write_to_vm) | 748 | int write_to_vm) |
752 | { | 749 | { |
753 | struct bio *bio; | 750 | struct bio *bio; |
754 | int len = 0, i; | ||
755 | 751 | ||
756 | bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm); | 752 | bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm); |
757 | 753 | ||
@@ -766,18 +762,7 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, | |||
766 | */ | 762 | */ |
767 | bio_get(bio); | 763 | bio_get(bio); |
768 | 764 | ||
769 | for (i = 0; i < iov_count; i++) | 765 | return bio; |
770 | len += iov[i].iov_len; | ||
771 | |||
772 | if (bio->bi_size == len) | ||
773 | return bio; | ||
774 | |||
775 | /* | ||
776 | * don't support partial mappings | ||
777 | */ | ||
778 | bio_endio(bio, bio->bi_size, 0); | ||
779 | bio_unmap_user(bio); | ||
780 | return ERR_PTR(-EINVAL); | ||
781 | } | 766 | } |
782 | 767 | ||
783 | static void __bio_unmap_user(struct bio *bio) | 768 | static void __bio_unmap_user(struct bio *bio) |
@@ -931,7 +916,7 @@ void bio_set_pages_dirty(struct bio *bio) | |||
931 | } | 916 | } |
932 | } | 917 | } |
933 | 918 | ||
934 | static void bio_release_pages(struct bio *bio) | 919 | void bio_release_pages(struct bio *bio) |
935 | { | 920 | { |
936 | struct bio_vec *bvec = bio->bi_io_vec; | 921 | struct bio_vec *bvec = bio->bi_io_vec; |
937 | int i; | 922 | int i; |
@@ -955,16 +940,16 @@ static void bio_release_pages(struct bio *bio) | |||
955 | * run one bio_put() against the BIO. | 940 | * run one bio_put() against the BIO. |
956 | */ | 941 | */ |
957 | 942 | ||
958 | static void bio_dirty_fn(void *data); | 943 | static void bio_dirty_fn(struct work_struct *work); |
959 | 944 | ||
960 | static DECLARE_WORK(bio_dirty_work, bio_dirty_fn, NULL); | 945 | static DECLARE_WORK(bio_dirty_work, bio_dirty_fn); |
961 | static DEFINE_SPINLOCK(bio_dirty_lock); | 946 | static DEFINE_SPINLOCK(bio_dirty_lock); |
962 | static struct bio *bio_dirty_list; | 947 | static struct bio *bio_dirty_list; |
963 | 948 | ||
964 | /* | 949 | /* |
965 | * This runs in process context | 950 | * This runs in process context |
966 | */ | 951 | */ |
967 | static void bio_dirty_fn(void *data) | 952 | static void bio_dirty_fn(struct work_struct *work) |
968 | { | 953 | { |
969 | unsigned long flags; | 954 | unsigned long flags; |
970 | struct bio *bio; | 955 | struct bio *bio; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 36c0e7af9d0f..8b18e43b82fe 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -129,43 +129,191 @@ blkdev_get_block(struct inode *inode, sector_t iblock, | |||
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | static int | 132 | static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error) |
133 | blkdev_get_blocks(struct inode *inode, sector_t iblock, | ||
134 | struct buffer_head *bh, int create) | ||
135 | { | 133 | { |
136 | sector_t end_block = max_block(I_BDEV(inode)); | 134 | struct kiocb *iocb = bio->bi_private; |
137 | unsigned long max_blocks = bh->b_size >> inode->i_blkbits; | 135 | atomic_t *bio_count = &iocb->ki_bio_count; |
138 | 136 | ||
139 | if ((iblock + max_blocks) > end_block) { | 137 | if (bio_data_dir(bio) == READ) |
140 | max_blocks = end_block - iblock; | 138 | bio_check_pages_dirty(bio); |
141 | if ((long)max_blocks <= 0) { | 139 | else { |
142 | if (create) | 140 | bio_release_pages(bio); |
143 | return -EIO; /* write fully beyond EOF */ | 141 | bio_put(bio); |
144 | /* | 142 | } |
145 | * It is a read which is fully beyond EOF. We return | 143 | |
146 | * a !buffer_mapped buffer | 144 | /* iocb->ki_nbytes stores error code from LLDD */ |
147 | */ | 145 | if (error) |
148 | max_blocks = 0; | 146 | iocb->ki_nbytes = -EIO; |
149 | } | 147 | |
148 | if (atomic_dec_and_test(bio_count)) { | ||
149 | if (iocb->ki_nbytes < 0) | ||
150 | aio_complete(iocb, iocb->ki_nbytes, 0); | ||
151 | else | ||
152 | aio_complete(iocb, iocb->ki_left, 0); | ||
150 | } | 153 | } |
151 | 154 | ||
152 | bh->b_bdev = I_BDEV(inode); | ||
153 | bh->b_blocknr = iblock; | ||
154 | bh->b_size = max_blocks << inode->i_blkbits; | ||
155 | if (max_blocks) | ||
156 | set_buffer_mapped(bh); | ||
157 | return 0; | 155 | return 0; |
158 | } | 156 | } |
159 | 157 | ||
158 | #define VEC_SIZE 16 | ||
159 | struct pvec { | ||
160 | unsigned short nr; | ||
161 | unsigned short idx; | ||
162 | struct page *page[VEC_SIZE]; | ||
163 | }; | ||
164 | |||
165 | #define PAGES_SPANNED(addr, len) \ | ||
166 | (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE); | ||
167 | |||
168 | /* | ||
169 | * get page pointer for user addr, we internally cache struct page array for | ||
170 | * (addr, count) range in pvec to avoid frequent call to get_user_pages. If | ||
171 | * internal page list is exhausted, a batch count of up to VEC_SIZE is used | ||
172 | * to get next set of page struct. | ||
173 | */ | ||
174 | static struct page *blk_get_page(unsigned long addr, size_t count, int rw, | ||
175 | struct pvec *pvec) | ||
176 | { | ||
177 | int ret, nr_pages; | ||
178 | if (pvec->idx == pvec->nr) { | ||
179 | nr_pages = PAGES_SPANNED(addr, count); | ||
180 | nr_pages = min(nr_pages, VEC_SIZE); | ||
181 | down_read(¤t->mm->mmap_sem); | ||
182 | ret = get_user_pages(current, current->mm, addr, nr_pages, | ||
183 | rw == READ, 0, pvec->page, NULL); | ||
184 | up_read(¤t->mm->mmap_sem); | ||
185 | if (ret < 0) | ||
186 | return ERR_PTR(ret); | ||
187 | pvec->nr = ret; | ||
188 | pvec->idx = 0; | ||
189 | } | ||
190 | return pvec->page[pvec->idx++]; | ||
191 | } | ||
192 | |||
160 | static ssize_t | 193 | static ssize_t |
161 | blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | 194 | blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, |
162 | loff_t offset, unsigned long nr_segs) | 195 | loff_t pos, unsigned long nr_segs) |
163 | { | 196 | { |
164 | struct file *file = iocb->ki_filp; | 197 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
165 | struct inode *inode = file->f_mapping->host; | 198 | unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode))); |
199 | unsigned blocksize_mask = (1 << blkbits) - 1; | ||
200 | unsigned long seg = 0; /* iov segment iterator */ | ||
201 | unsigned long nvec; /* number of bio vec needed */ | ||
202 | unsigned long cur_off; /* offset into current page */ | ||
203 | unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */ | ||
204 | |||
205 | unsigned long addr; /* user iovec address */ | ||
206 | size_t count; /* user iovec len */ | ||
207 | size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */ | ||
208 | loff_t size; /* size of block device */ | ||
209 | struct bio *bio; | ||
210 | atomic_t *bio_count = &iocb->ki_bio_count; | ||
211 | struct page *page; | ||
212 | struct pvec pvec; | ||
213 | |||
214 | pvec.nr = 0; | ||
215 | pvec.idx = 0; | ||
216 | |||
217 | if (pos & blocksize_mask) | ||
218 | return -EINVAL; | ||
219 | |||
220 | size = i_size_read(inode); | ||
221 | if (pos + nbytes > size) { | ||
222 | nbytes = size - pos; | ||
223 | iocb->ki_left = nbytes; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * check first non-zero iov alignment, the remaining | ||
228 | * iov alignment is checked inside bio loop below. | ||
229 | */ | ||
230 | do { | ||
231 | addr = (unsigned long) iov[seg].iov_base; | ||
232 | count = min(iov[seg].iov_len, nbytes); | ||
233 | if (addr & blocksize_mask || count & blocksize_mask) | ||
234 | return -EINVAL; | ||
235 | } while (!count && ++seg < nr_segs); | ||
236 | atomic_set(bio_count, 1); | ||
237 | |||
238 | while (nbytes) { | ||
239 | /* roughly estimate number of bio vec needed */ | ||
240 | nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE; | ||
241 | nvec = max(nvec, nr_segs - seg); | ||
242 | nvec = min(nvec, (unsigned long) BIO_MAX_PAGES); | ||
243 | |||
244 | /* bio_alloc should not fail with GFP_KERNEL flag */ | ||
245 | bio = bio_alloc(GFP_KERNEL, nvec); | ||
246 | bio->bi_bdev = I_BDEV(inode); | ||
247 | bio->bi_end_io = blk_end_aio; | ||
248 | bio->bi_private = iocb; | ||
249 | bio->bi_sector = pos >> blkbits; | ||
250 | same_bio: | ||
251 | cur_off = addr & ~PAGE_MASK; | ||
252 | cur_len = PAGE_SIZE - cur_off; | ||
253 | if (count < cur_len) | ||
254 | cur_len = count; | ||
255 | |||
256 | page = blk_get_page(addr, count, rw, &pvec); | ||
257 | if (unlikely(IS_ERR(page))) | ||
258 | goto backout; | ||
259 | |||
260 | if (bio_add_page(bio, page, cur_len, cur_off)) { | ||
261 | pos += cur_len; | ||
262 | addr += cur_len; | ||
263 | count -= cur_len; | ||
264 | nbytes -= cur_len; | ||
265 | |||
266 | if (count) | ||
267 | goto same_bio; | ||
268 | while (++seg < nr_segs) { | ||
269 | addr = (unsigned long) iov[seg].iov_base; | ||
270 | count = iov[seg].iov_len; | ||
271 | if (!count) | ||
272 | continue; | ||
273 | if (unlikely(addr & blocksize_mask || | ||
274 | count & blocksize_mask)) { | ||
275 | page = ERR_PTR(-EINVAL); | ||
276 | goto backout; | ||
277 | } | ||
278 | count = min(count, nbytes); | ||
279 | goto same_bio; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | /* bio is ready, submit it */ | ||
284 | if (rw == READ) | ||
285 | bio_set_pages_dirty(bio); | ||
286 | atomic_inc(bio_count); | ||
287 | submit_bio(rw, bio); | ||
288 | } | ||
289 | |||
290 | completion: | ||
291 | iocb->ki_left -= nbytes; | ||
292 | nbytes = iocb->ki_left; | ||
293 | iocb->ki_pos += nbytes; | ||
294 | |||
295 | blk_run_address_space(inode->i_mapping); | ||
296 | if (atomic_dec_and_test(bio_count)) | ||
297 | aio_complete(iocb, nbytes, 0); | ||
298 | |||
299 | return -EIOCBQUEUED; | ||
166 | 300 | ||
167 | return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode), | 301 | backout: |
168 | iov, offset, nr_segs, blkdev_get_blocks, NULL); | 302 | /* |
303 | * back out nbytes count constructed so far for this bio, | ||
304 | * we will throw away current bio. | ||
305 | */ | ||
306 | nbytes += bio->bi_size; | ||
307 | bio_release_pages(bio); | ||
308 | bio_put(bio); | ||
309 | |||
310 | /* | ||
311 | * if no bio was submmitted, return the error code. | ||
312 | * otherwise, proceed with pending I/O completion. | ||
313 | */ | ||
314 | if (atomic_read(bio_count) == 1) | ||
315 | return PTR_ERR(page); | ||
316 | goto completion; | ||
169 | } | 317 | } |
170 | 318 | ||
171 | static int blkdev_writepage(struct page *page, struct writeback_control *wbc) | 319 | static int blkdev_writepage(struct page *page, struct writeback_control *wbc) |
@@ -190,7 +338,7 @@ static int blkdev_commit_write(struct file *file, struct page *page, unsigned fr | |||
190 | 338 | ||
191 | /* | 339 | /* |
192 | * private llseek: | 340 | * private llseek: |
193 | * for a block special file file->f_dentry->d_inode->i_size is zero | 341 | * for a block special file file->f_path.dentry->d_inode->i_size is zero |
194 | * so we compute the size by hand (just as in block_read/write above) | 342 | * so we compute the size by hand (just as in block_read/write above) |
195 | */ | 343 | */ |
196 | static loff_t block_llseek(struct file *file, loff_t offset, int origin) | 344 | static loff_t block_llseek(struct file *file, loff_t offset, int origin) |
@@ -235,11 +383,11 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) | |||
235 | */ | 383 | */ |
236 | 384 | ||
237 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); | 385 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); |
238 | static kmem_cache_t * bdev_cachep __read_mostly; | 386 | static struct kmem_cache * bdev_cachep __read_mostly; |
239 | 387 | ||
240 | static struct inode *bdev_alloc_inode(struct super_block *sb) | 388 | static struct inode *bdev_alloc_inode(struct super_block *sb) |
241 | { | 389 | { |
242 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); | 390 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); |
243 | if (!ei) | 391 | if (!ei) |
244 | return NULL; | 392 | return NULL; |
245 | return &ei->vfs_inode; | 393 | return &ei->vfs_inode; |
@@ -253,7 +401,7 @@ static void bdev_destroy_inode(struct inode *inode) | |||
253 | kmem_cache_free(bdev_cachep, bdi); | 401 | kmem_cache_free(bdev_cachep, bdi); |
254 | } | 402 | } |
255 | 403 | ||
256 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 404 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
257 | { | 405 | { |
258 | struct bdev_inode *ei = (struct bdev_inode *) foo; | 406 | struct bdev_inode *ei = (struct bdev_inode *) foo; |
259 | struct block_device *bdev = &ei->bdev; | 407 | struct block_device *bdev = &ei->bdev; |
@@ -263,7 +411,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | |||
263 | { | 411 | { |
264 | memset(bdev, 0, sizeof(*bdev)); | 412 | memset(bdev, 0, sizeof(*bdev)); |
265 | mutex_init(&bdev->bd_mutex); | 413 | mutex_init(&bdev->bd_mutex); |
266 | mutex_init(&bdev->bd_mount_mutex); | 414 | sema_init(&bdev->bd_mount_sem, 1); |
267 | INIT_LIST_HEAD(&bdev->bd_inodes); | 415 | INIT_LIST_HEAD(&bdev->bd_inodes); |
268 | INIT_LIST_HEAD(&bdev->bd_list); | 416 | INIT_LIST_HEAD(&bdev->bd_list); |
269 | #ifdef CONFIG_SYSFS | 417 | #ifdef CONFIG_SYSFS |
@@ -762,7 +910,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | |||
762 | if (!bo) | 910 | if (!bo) |
763 | return -ENOMEM; | 911 | return -ENOMEM; |
764 | 912 | ||
765 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); | 913 | mutex_lock(&bdev->bd_mutex); |
766 | res = bd_claim(bdev, holder); | 914 | res = bd_claim(bdev, holder); |
767 | if (res == 0) { | 915 | if (res == 0) { |
768 | found = find_bd_holder(bdev, bo); | 916 | found = find_bd_holder(bdev, bo); |
@@ -796,7 +944,7 @@ static void bd_release_from_kobject(struct block_device *bdev, | |||
796 | if (!kobj) | 944 | if (!kobj) |
797 | return; | 945 | return; |
798 | 946 | ||
799 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); | 947 | mutex_lock(&bdev->bd_mutex); |
800 | bd_release(bdev); | 948 | bd_release(bdev); |
801 | if ((bo = del_bd_holder(bdev, kobj))) | 949 | if ((bo = del_bd_holder(bdev, kobj))) |
802 | free_bd_holder(bo); | 950 | free_bd_holder(bo); |
@@ -854,22 +1002,6 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode) | |||
854 | 1002 | ||
855 | EXPORT_SYMBOL(open_by_devnum); | 1003 | EXPORT_SYMBOL(open_by_devnum); |
856 | 1004 | ||
857 | static int | ||
858 | blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags); | ||
859 | |||
860 | struct block_device *open_partition_by_devnum(dev_t dev, unsigned mode) | ||
861 | { | ||
862 | struct block_device *bdev = bdget(dev); | ||
863 | int err = -ENOMEM; | ||
864 | int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY; | ||
865 | if (bdev) | ||
866 | err = blkdev_get_partition(bdev, mode, flags); | ||
867 | return err ? ERR_PTR(err) : bdev; | ||
868 | } | ||
869 | |||
870 | EXPORT_SYMBOL(open_partition_by_devnum); | ||
871 | |||
872 | |||
873 | /* | 1005 | /* |
874 | * This routine checks whether a removable media has been changed, | 1006 | * This routine checks whether a removable media has been changed, |
875 | * and invalidates all buffer-cache-entries in that case. This | 1007 | * and invalidates all buffer-cache-entries in that case. This |
@@ -916,66 +1048,11 @@ void bd_set_size(struct block_device *bdev, loff_t size) | |||
916 | } | 1048 | } |
917 | EXPORT_SYMBOL(bd_set_size); | 1049 | EXPORT_SYMBOL(bd_set_size); |
918 | 1050 | ||
919 | static int __blkdev_put(struct block_device *bdev, unsigned int subclass) | 1051 | static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, |
920 | { | 1052 | int for_part); |
921 | int ret = 0; | 1053 | static int __blkdev_put(struct block_device *bdev, int for_part); |
922 | struct inode *bd_inode = bdev->bd_inode; | ||
923 | struct gendisk *disk = bdev->bd_disk; | ||
924 | 1054 | ||
925 | mutex_lock_nested(&bdev->bd_mutex, subclass); | 1055 | static int do_open(struct block_device *bdev, struct file *file, int for_part) |
926 | lock_kernel(); | ||
927 | if (!--bdev->bd_openers) { | ||
928 | sync_blockdev(bdev); | ||
929 | kill_bdev(bdev); | ||
930 | } | ||
931 | if (bdev->bd_contains == bdev) { | ||
932 | if (disk->fops->release) | ||
933 | ret = disk->fops->release(bd_inode, NULL); | ||
934 | } else { | ||
935 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, | ||
936 | subclass + 1); | ||
937 | bdev->bd_contains->bd_part_count--; | ||
938 | mutex_unlock(&bdev->bd_contains->bd_mutex); | ||
939 | } | ||
940 | if (!bdev->bd_openers) { | ||
941 | struct module *owner = disk->fops->owner; | ||
942 | |||
943 | put_disk(disk); | ||
944 | module_put(owner); | ||
945 | |||
946 | if (bdev->bd_contains != bdev) { | ||
947 | kobject_put(&bdev->bd_part->kobj); | ||
948 | bdev->bd_part = NULL; | ||
949 | } | ||
950 | bdev->bd_disk = NULL; | ||
951 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | ||
952 | if (bdev != bdev->bd_contains) | ||
953 | __blkdev_put(bdev->bd_contains, subclass + 1); | ||
954 | bdev->bd_contains = NULL; | ||
955 | } | ||
956 | unlock_kernel(); | ||
957 | mutex_unlock(&bdev->bd_mutex); | ||
958 | bdput(bdev); | ||
959 | return ret; | ||
960 | } | ||
961 | |||
962 | int blkdev_put(struct block_device *bdev) | ||
963 | { | ||
964 | return __blkdev_put(bdev, BD_MUTEX_NORMAL); | ||
965 | } | ||
966 | EXPORT_SYMBOL(blkdev_put); | ||
967 | |||
968 | int blkdev_put_partition(struct block_device *bdev) | ||
969 | { | ||
970 | return __blkdev_put(bdev, BD_MUTEX_PARTITION); | ||
971 | } | ||
972 | EXPORT_SYMBOL(blkdev_put_partition); | ||
973 | |||
974 | static int | ||
975 | blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags); | ||
976 | |||
977 | static int | ||
978 | do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | ||
979 | { | 1056 | { |
980 | struct module *owner = NULL; | 1057 | struct module *owner = NULL; |
981 | struct gendisk *disk; | 1058 | struct gendisk *disk; |
@@ -992,8 +1069,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | |||
992 | } | 1069 | } |
993 | owner = disk->fops->owner; | 1070 | owner = disk->fops->owner; |
994 | 1071 | ||
995 | mutex_lock_nested(&bdev->bd_mutex, subclass); | 1072 | mutex_lock_nested(&bdev->bd_mutex, for_part); |
996 | |||
997 | if (!bdev->bd_openers) { | 1073 | if (!bdev->bd_openers) { |
998 | bdev->bd_disk = disk; | 1074 | bdev->bd_disk = disk; |
999 | bdev->bd_contains = bdev; | 1075 | bdev->bd_contains = bdev; |
@@ -1020,25 +1096,21 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | |||
1020 | ret = -ENOMEM; | 1096 | ret = -ENOMEM; |
1021 | if (!whole) | 1097 | if (!whole) |
1022 | goto out_first; | 1098 | goto out_first; |
1023 | ret = blkdev_get_whole(whole, file->f_mode, file->f_flags); | 1099 | BUG_ON(for_part); |
1100 | ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); | ||
1024 | if (ret) | 1101 | if (ret) |
1025 | goto out_first; | 1102 | goto out_first; |
1026 | bdev->bd_contains = whole; | 1103 | bdev->bd_contains = whole; |
1027 | mutex_lock_nested(&whole->bd_mutex, BD_MUTEX_WHOLE); | ||
1028 | whole->bd_part_count++; | ||
1029 | p = disk->part[part - 1]; | 1104 | p = disk->part[part - 1]; |
1030 | bdev->bd_inode->i_data.backing_dev_info = | 1105 | bdev->bd_inode->i_data.backing_dev_info = |
1031 | whole->bd_inode->i_data.backing_dev_info; | 1106 | whole->bd_inode->i_data.backing_dev_info; |
1032 | if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) { | 1107 | if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) { |
1033 | whole->bd_part_count--; | ||
1034 | mutex_unlock(&whole->bd_mutex); | ||
1035 | ret = -ENXIO; | 1108 | ret = -ENXIO; |
1036 | goto out_first; | 1109 | goto out_first; |
1037 | } | 1110 | } |
1038 | kobject_get(&p->kobj); | 1111 | kobject_get(&p->kobj); |
1039 | bdev->bd_part = p; | 1112 | bdev->bd_part = p; |
1040 | bd_set_size(bdev, (loff_t) p->nr_sects << 9); | 1113 | bd_set_size(bdev, (loff_t) p->nr_sects << 9); |
1041 | mutex_unlock(&whole->bd_mutex); | ||
1042 | } | 1114 | } |
1043 | } else { | 1115 | } else { |
1044 | put_disk(disk); | 1116 | put_disk(disk); |
@@ -1051,14 +1123,11 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | |||
1051 | } | 1123 | } |
1052 | if (bdev->bd_invalidated) | 1124 | if (bdev->bd_invalidated) |
1053 | rescan_partitions(bdev->bd_disk, bdev); | 1125 | rescan_partitions(bdev->bd_disk, bdev); |
1054 | } else { | ||
1055 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, | ||
1056 | BD_MUTEX_WHOLE); | ||
1057 | bdev->bd_contains->bd_part_count++; | ||
1058 | mutex_unlock(&bdev->bd_contains->bd_mutex); | ||
1059 | } | 1126 | } |
1060 | } | 1127 | } |
1061 | bdev->bd_openers++; | 1128 | bdev->bd_openers++; |
1129 | if (for_part) | ||
1130 | bdev->bd_part_count++; | ||
1062 | mutex_unlock(&bdev->bd_mutex); | 1131 | mutex_unlock(&bdev->bd_mutex); |
1063 | unlock_kernel(); | 1132 | unlock_kernel(); |
1064 | return 0; | 1133 | return 0; |
@@ -1067,7 +1136,7 @@ out_first: | |||
1067 | bdev->bd_disk = NULL; | 1136 | bdev->bd_disk = NULL; |
1068 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | 1137 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; |
1069 | if (bdev != bdev->bd_contains) | 1138 | if (bdev != bdev->bd_contains) |
1070 | __blkdev_put(bdev->bd_contains, BD_MUTEX_WHOLE); | 1139 | __blkdev_put(bdev->bd_contains, 1); |
1071 | bdev->bd_contains = NULL; | 1140 | bdev->bd_contains = NULL; |
1072 | put_disk(disk); | 1141 | put_disk(disk); |
1073 | module_put(owner); | 1142 | module_put(owner); |
@@ -1079,7 +1148,8 @@ out: | |||
1079 | return ret; | 1148 | return ret; |
1080 | } | 1149 | } |
1081 | 1150 | ||
1082 | int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) | 1151 | static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, |
1152 | int for_part) | ||
1083 | { | 1153 | { |
1084 | /* | 1154 | /* |
1085 | * This crockload is due to bad choice of ->open() type. | 1155 | * This crockload is due to bad choice of ->open() type. |
@@ -1091,51 +1161,17 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) | |||
1091 | struct dentry fake_dentry = {}; | 1161 | struct dentry fake_dentry = {}; |
1092 | fake_file.f_mode = mode; | 1162 | fake_file.f_mode = mode; |
1093 | fake_file.f_flags = flags; | 1163 | fake_file.f_flags = flags; |
1094 | fake_file.f_dentry = &fake_dentry; | 1164 | fake_file.f_path.dentry = &fake_dentry; |
1095 | fake_dentry.d_inode = bdev->bd_inode; | 1165 | fake_dentry.d_inode = bdev->bd_inode; |
1096 | 1166 | ||
1097 | return do_open(bdev, &fake_file, BD_MUTEX_NORMAL); | 1167 | return do_open(bdev, &fake_file, for_part); |
1098 | } | 1168 | } |
1099 | 1169 | ||
1100 | EXPORT_SYMBOL(blkdev_get); | 1170 | int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) |
1101 | |||
1102 | static int | ||
1103 | blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags) | ||
1104 | { | ||
1105 | /* | ||
1106 | * This crockload is due to bad choice of ->open() type. | ||
1107 | * It will go away. | ||
1108 | * For now, block device ->open() routine must _not_ | ||
1109 | * examine anything in 'inode' argument except ->i_rdev. | ||
1110 | */ | ||
1111 | struct file fake_file = {}; | ||
1112 | struct dentry fake_dentry = {}; | ||
1113 | fake_file.f_mode = mode; | ||
1114 | fake_file.f_flags = flags; | ||
1115 | fake_file.f_dentry = &fake_dentry; | ||
1116 | fake_dentry.d_inode = bdev->bd_inode; | ||
1117 | |||
1118 | return do_open(bdev, &fake_file, BD_MUTEX_WHOLE); | ||
1119 | } | ||
1120 | |||
1121 | static int | ||
1122 | blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags) | ||
1123 | { | 1171 | { |
1124 | /* | 1172 | return __blkdev_get(bdev, mode, flags, 0); |
1125 | * This crockload is due to bad choice of ->open() type. | ||
1126 | * It will go away. | ||
1127 | * For now, block device ->open() routine must _not_ | ||
1128 | * examine anything in 'inode' argument except ->i_rdev. | ||
1129 | */ | ||
1130 | struct file fake_file = {}; | ||
1131 | struct dentry fake_dentry = {}; | ||
1132 | fake_file.f_mode = mode; | ||
1133 | fake_file.f_flags = flags; | ||
1134 | fake_file.f_dentry = &fake_dentry; | ||
1135 | fake_dentry.d_inode = bdev->bd_inode; | ||
1136 | |||
1137 | return do_open(bdev, &fake_file, BD_MUTEX_PARTITION); | ||
1138 | } | 1173 | } |
1174 | EXPORT_SYMBOL(blkdev_get); | ||
1139 | 1175 | ||
1140 | static int blkdev_open(struct inode * inode, struct file * filp) | 1176 | static int blkdev_open(struct inode * inode, struct file * filp) |
1141 | { | 1177 | { |
@@ -1154,7 +1190,7 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1154 | if (bdev == NULL) | 1190 | if (bdev == NULL) |
1155 | return -ENOMEM; | 1191 | return -ENOMEM; |
1156 | 1192 | ||
1157 | res = do_open(bdev, filp, BD_MUTEX_NORMAL); | 1193 | res = do_open(bdev, filp, 0); |
1158 | if (res) | 1194 | if (res) |
1159 | return res; | 1195 | return res; |
1160 | 1196 | ||
@@ -1168,6 +1204,56 @@ static int blkdev_open(struct inode * inode, struct file * filp) | |||
1168 | return res; | 1204 | return res; |
1169 | } | 1205 | } |
1170 | 1206 | ||
1207 | static int __blkdev_put(struct block_device *bdev, int for_part) | ||
1208 | { | ||
1209 | int ret = 0; | ||
1210 | struct inode *bd_inode = bdev->bd_inode; | ||
1211 | struct gendisk *disk = bdev->bd_disk; | ||
1212 | struct block_device *victim = NULL; | ||
1213 | |||
1214 | mutex_lock_nested(&bdev->bd_mutex, for_part); | ||
1215 | lock_kernel(); | ||
1216 | if (for_part) | ||
1217 | bdev->bd_part_count--; | ||
1218 | |||
1219 | if (!--bdev->bd_openers) { | ||
1220 | sync_blockdev(bdev); | ||
1221 | kill_bdev(bdev); | ||
1222 | } | ||
1223 | if (bdev->bd_contains == bdev) { | ||
1224 | if (disk->fops->release) | ||
1225 | ret = disk->fops->release(bd_inode, NULL); | ||
1226 | } | ||
1227 | if (!bdev->bd_openers) { | ||
1228 | struct module *owner = disk->fops->owner; | ||
1229 | |||
1230 | put_disk(disk); | ||
1231 | module_put(owner); | ||
1232 | |||
1233 | if (bdev->bd_contains != bdev) { | ||
1234 | kobject_put(&bdev->bd_part->kobj); | ||
1235 | bdev->bd_part = NULL; | ||
1236 | } | ||
1237 | bdev->bd_disk = NULL; | ||
1238 | bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; | ||
1239 | if (bdev != bdev->bd_contains) | ||
1240 | victim = bdev->bd_contains; | ||
1241 | bdev->bd_contains = NULL; | ||
1242 | } | ||
1243 | unlock_kernel(); | ||
1244 | mutex_unlock(&bdev->bd_mutex); | ||
1245 | bdput(bdev); | ||
1246 | if (victim) | ||
1247 | __blkdev_put(victim, 1); | ||
1248 | return ret; | ||
1249 | } | ||
1250 | |||
1251 | int blkdev_put(struct block_device *bdev) | ||
1252 | { | ||
1253 | return __blkdev_put(bdev, 0); | ||
1254 | } | ||
1255 | EXPORT_SYMBOL(blkdev_put); | ||
1256 | |||
1171 | static int blkdev_close(struct inode * inode, struct file * filp) | 1257 | static int blkdev_close(struct inode * inode, struct file * filp) |
1172 | { | 1258 | { |
1173 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 1259 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); |
diff --git a/fs/buffer.c b/fs/buffer.c index 35527dca1dbc..3b116078b4c3 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/hash.h> | 35 | #include <linux/hash.h> |
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/task_io_accounting_ops.h> | ||
38 | #include <linux/bio.h> | 39 | #include <linux/bio.h> |
39 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
40 | #include <linux/cpu.h> | 41 | #include <linux/cpu.h> |
@@ -179,7 +180,7 @@ int fsync_bdev(struct block_device *bdev) | |||
179 | * freeze_bdev -- lock a filesystem and force it into a consistent state | 180 | * freeze_bdev -- lock a filesystem and force it into a consistent state |
180 | * @bdev: blockdevice to lock | 181 | * @bdev: blockdevice to lock |
181 | * | 182 | * |
182 | * This takes the block device bd_mount_mutex to make sure no new mounts | 183 | * This takes the block device bd_mount_sem to make sure no new mounts |
183 | * happen on bdev until thaw_bdev() is called. | 184 | * happen on bdev until thaw_bdev() is called. |
184 | * If a superblock is found on this device, we take the s_umount semaphore | 185 | * If a superblock is found on this device, we take the s_umount semaphore |
185 | * on it to make sure nobody unmounts until the snapshot creation is done. | 186 | * on it to make sure nobody unmounts until the snapshot creation is done. |
@@ -188,7 +189,7 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
188 | { | 189 | { |
189 | struct super_block *sb; | 190 | struct super_block *sb; |
190 | 191 | ||
191 | mutex_lock(&bdev->bd_mount_mutex); | 192 | down(&bdev->bd_mount_sem); |
192 | sb = get_super(bdev); | 193 | sb = get_super(bdev); |
193 | if (sb && !(sb->s_flags & MS_RDONLY)) { | 194 | if (sb && !(sb->s_flags & MS_RDONLY)) { |
194 | sb->s_frozen = SB_FREEZE_WRITE; | 195 | sb->s_frozen = SB_FREEZE_WRITE; |
@@ -230,7 +231,7 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
230 | drop_super(sb); | 231 | drop_super(sb); |
231 | } | 232 | } |
232 | 233 | ||
233 | mutex_unlock(&bdev->bd_mount_mutex); | 234 | up(&bdev->bd_mount_sem); |
234 | } | 235 | } |
235 | EXPORT_SYMBOL(thaw_bdev); | 236 | EXPORT_SYMBOL(thaw_bdev); |
236 | 237 | ||
@@ -724,20 +725,21 @@ int __set_page_dirty_buffers(struct page *page) | |||
724 | } | 725 | } |
725 | spin_unlock(&mapping->private_lock); | 726 | spin_unlock(&mapping->private_lock); |
726 | 727 | ||
727 | if (!TestSetPageDirty(page)) { | 728 | if (TestSetPageDirty(page)) |
728 | write_lock_irq(&mapping->tree_lock); | 729 | return 0; |
729 | if (page->mapping) { /* Race with truncate? */ | 730 | |
730 | if (mapping_cap_account_dirty(mapping)) | 731 | write_lock_irq(&mapping->tree_lock); |
731 | __inc_zone_page_state(page, NR_FILE_DIRTY); | 732 | if (page->mapping) { /* Race with truncate? */ |
732 | radix_tree_tag_set(&mapping->page_tree, | 733 | if (mapping_cap_account_dirty(mapping)) { |
733 | page_index(page), | 734 | __inc_zone_page_state(page, NR_FILE_DIRTY); |
734 | PAGECACHE_TAG_DIRTY); | 735 | task_io_account_write(PAGE_CACHE_SIZE); |
735 | } | 736 | } |
736 | write_unlock_irq(&mapping->tree_lock); | 737 | radix_tree_tag_set(&mapping->page_tree, |
737 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | 738 | page_index(page), PAGECACHE_TAG_DIRTY); |
738 | return 1; | ||
739 | } | 739 | } |
740 | return 0; | 740 | write_unlock_irq(&mapping->tree_lock); |
741 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
742 | return 1; | ||
741 | } | 743 | } |
742 | EXPORT_SYMBOL(__set_page_dirty_buffers); | 744 | EXPORT_SYMBOL(__set_page_dirty_buffers); |
743 | 745 | ||
@@ -2832,7 +2834,7 @@ int try_to_free_buffers(struct page *page) | |||
2832 | int ret = 0; | 2834 | int ret = 0; |
2833 | 2835 | ||
2834 | BUG_ON(!PageLocked(page)); | 2836 | BUG_ON(!PageLocked(page)); |
2835 | if (PageWriteback(page)) | 2837 | if (PageDirty(page) || PageWriteback(page)) |
2836 | return 0; | 2838 | return 0; |
2837 | 2839 | ||
2838 | if (mapping == NULL) { /* can this still happen? */ | 2840 | if (mapping == NULL) { /* can this still happen? */ |
@@ -2843,17 +2845,6 @@ int try_to_free_buffers(struct page *page) | |||
2843 | spin_lock(&mapping->private_lock); | 2845 | spin_lock(&mapping->private_lock); |
2844 | ret = drop_buffers(page, &buffers_to_free); | 2846 | ret = drop_buffers(page, &buffers_to_free); |
2845 | spin_unlock(&mapping->private_lock); | 2847 | spin_unlock(&mapping->private_lock); |
2846 | if (ret) { | ||
2847 | /* | ||
2848 | * If the filesystem writes its buffers by hand (eg ext3) | ||
2849 | * then we can have clean buffers against a dirty page. We | ||
2850 | * clean the page here; otherwise later reattachment of buffers | ||
2851 | * could encounter a non-uptodate page, which is unresolvable. | ||
2852 | * This only applies in the rare case where try_to_free_buffers | ||
2853 | * succeeds but the page is not freed. | ||
2854 | */ | ||
2855 | clear_page_dirty(page); | ||
2856 | } | ||
2857 | out: | 2848 | out: |
2858 | if (buffers_to_free) { | 2849 | if (buffers_to_free) { |
2859 | struct buffer_head *bh = buffers_to_free; | 2850 | struct buffer_head *bh = buffers_to_free; |
@@ -2908,7 +2899,7 @@ asmlinkage long sys_bdflush(int func, long data) | |||
2908 | /* | 2899 | /* |
2909 | * Buffer-head allocation | 2900 | * Buffer-head allocation |
2910 | */ | 2901 | */ |
2911 | static kmem_cache_t *bh_cachep; | 2902 | static struct kmem_cache *bh_cachep; |
2912 | 2903 | ||
2913 | /* | 2904 | /* |
2914 | * Once the number of bh's in the machine exceeds this level, we start | 2905 | * Once the number of bh's in the machine exceeds this level, we start |
@@ -2961,7 +2952,7 @@ void free_buffer_head(struct buffer_head *bh) | |||
2961 | EXPORT_SYMBOL(free_buffer_head); | 2952 | EXPORT_SYMBOL(free_buffer_head); |
2962 | 2953 | ||
2963 | static void | 2954 | static void |
2964 | init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) | 2955 | init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) |
2965 | { | 2956 | { |
2966 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 2957 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
2967 | SLAB_CTOR_CONSTRUCTOR) { | 2958 | SLAB_CTOR_CONSTRUCTOR) { |
@@ -2972,7 +2963,6 @@ init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) | |||
2972 | } | 2963 | } |
2973 | } | 2964 | } |
2974 | 2965 | ||
2975 | #ifdef CONFIG_HOTPLUG_CPU | ||
2976 | static void buffer_exit_cpu(int cpu) | 2966 | static void buffer_exit_cpu(int cpu) |
2977 | { | 2967 | { |
2978 | int i; | 2968 | int i; |
@@ -2994,7 +2984,6 @@ static int buffer_cpu_notify(struct notifier_block *self, | |||
2994 | buffer_exit_cpu((unsigned long)hcpu); | 2984 | buffer_exit_cpu((unsigned long)hcpu); |
2995 | return NOTIFY_OK; | 2985 | return NOTIFY_OK; |
2996 | } | 2986 | } |
2997 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
2998 | 2987 | ||
2999 | void __init buffer_init(void) | 2988 | void __init buffer_init(void) |
3000 | { | 2989 | { |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 0b3c37ef52e0..3539d6ef9611 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -5,7 +5,8 @@ Allow null user to be specified on mount ("username="). Do not return | |||
5 | EINVAL on readdir when filldir fails due to overwritten blocksize | 5 | EINVAL on readdir when filldir fails due to overwritten blocksize |
6 | (fixes FC problem). Return error in rename 2nd attempt retry (ie report | 6 | (fixes FC problem). Return error in rename 2nd attempt retry (ie report |
7 | if rename by handle also fails, after rename by path fails, we were | 7 | if rename by handle also fails, after rename by path fails, we were |
8 | not reporting whether the retry worked or not). | 8 | not reporting whether the retry worked or not). Fix NTLMv2 to |
9 | work to Windows servers (mount with option "sec=ntlmv2"). | ||
9 | 10 | ||
10 | Version 1.45 | 11 | Version 1.45 |
11 | ------------ | 12 | ------------ |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 4bc250b2d9fc..fdeda519eace 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -372,8 +372,10 @@ void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, | |||
372 | buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); | 372 | buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); |
373 | get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); | 373 | get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); |
374 | buf->reserved2 = 0; | 374 | buf->reserved2 = 0; |
375 | buf->names[0].type = 0; | 375 | buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); |
376 | buf->names[0].length = 0; | 376 | buf->names[0].length = 0; |
377 | buf->names[1].type = 0; | ||
378 | buf->names[1].length = 0; | ||
377 | 379 | ||
378 | /* calculate buf->ntlmv2_hash */ | 380 | /* calculate buf->ntlmv2_hash */ |
379 | rc = calc_ntlmv2_hash(ses, nls_cp); | 381 | rc = calc_ntlmv2_hash(ses, nls_cp); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 84976cdbe713..10c90294cd18 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mempool.h> | 34 | #include <linux/mempool.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | ||
37 | #include "cifsfs.h" | 38 | #include "cifsfs.h" |
38 | #include "cifspdu.h" | 39 | #include "cifspdu.h" |
39 | #define DECLARE_GLOBALS_HERE | 40 | #define DECLARE_GLOBALS_HERE |
@@ -81,7 +82,7 @@ extern mempool_t *cifs_sm_req_poolp; | |||
81 | extern mempool_t *cifs_req_poolp; | 82 | extern mempool_t *cifs_req_poolp; |
82 | extern mempool_t *cifs_mid_poolp; | 83 | extern mempool_t *cifs_mid_poolp; |
83 | 84 | ||
84 | extern kmem_cache_t *cifs_oplock_cachep; | 85 | extern struct kmem_cache *cifs_oplock_cachep; |
85 | 86 | ||
86 | static int | 87 | static int |
87 | cifs_read_super(struct super_block *sb, void *data, | 88 | cifs_read_super(struct super_block *sb, void *data, |
@@ -232,11 +233,11 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) | |||
232 | return generic_permission(inode, mask, NULL); | 233 | return generic_permission(inode, mask, NULL); |
233 | } | 234 | } |
234 | 235 | ||
235 | static kmem_cache_t *cifs_inode_cachep; | 236 | static struct kmem_cache *cifs_inode_cachep; |
236 | static kmem_cache_t *cifs_req_cachep; | 237 | static struct kmem_cache *cifs_req_cachep; |
237 | static kmem_cache_t *cifs_mid_cachep; | 238 | static struct kmem_cache *cifs_mid_cachep; |
238 | kmem_cache_t *cifs_oplock_cachep; | 239 | struct kmem_cache *cifs_oplock_cachep; |
239 | static kmem_cache_t *cifs_sm_req_cachep; | 240 | static struct kmem_cache *cifs_sm_req_cachep; |
240 | mempool_t *cifs_sm_req_poolp; | 241 | mempool_t *cifs_sm_req_poolp; |
241 | mempool_t *cifs_req_poolp; | 242 | mempool_t *cifs_req_poolp; |
242 | mempool_t *cifs_mid_poolp; | 243 | mempool_t *cifs_mid_poolp; |
@@ -245,7 +246,7 @@ static struct inode * | |||
245 | cifs_alloc_inode(struct super_block *sb) | 246 | cifs_alloc_inode(struct super_block *sb) |
246 | { | 247 | { |
247 | struct cifsInodeInfo *cifs_inode; | 248 | struct cifsInodeInfo *cifs_inode; |
248 | cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL); | 249 | cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL); |
249 | if (!cifs_inode) | 250 | if (!cifs_inode) |
250 | return NULL; | 251 | return NULL; |
251 | cifs_inode->cifsAttrs = 0x20; /* default */ | 252 | cifs_inode->cifsAttrs = 0x20; /* default */ |
@@ -497,7 +498,7 @@ cifs_get_sb(struct file_system_type *fs_type, | |||
497 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 498 | static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
498 | unsigned long nr_segs, loff_t pos) | 499 | unsigned long nr_segs, loff_t pos) |
499 | { | 500 | { |
500 | struct inode *inode = iocb->ki_filp->f_dentry->d_inode; | 501 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
501 | ssize_t written; | 502 | ssize_t written; |
502 | 503 | ||
503 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); | 504 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); |
@@ -510,7 +511,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | |||
510 | { | 511 | { |
511 | /* origin == SEEK_END => we must revalidate the cached file length */ | 512 | /* origin == SEEK_END => we must revalidate the cached file length */ |
512 | if (origin == SEEK_END) { | 513 | if (origin == SEEK_END) { |
513 | int retval = cifs_revalidate(file->f_dentry); | 514 | int retval = cifs_revalidate(file->f_path.dentry); |
514 | if (retval < 0) | 515 | if (retval < 0) |
515 | return (loff_t)retval; | 516 | return (loff_t)retval; |
516 | } | 517 | } |
@@ -668,7 +669,7 @@ const struct file_operations cifs_dir_ops = { | |||
668 | }; | 669 | }; |
669 | 670 | ||
670 | static void | 671 | static void |
671 | cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags) | 672 | cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) |
672 | { | 673 | { |
673 | struct cifsInodeInfo *cifsi = inode; | 674 | struct cifsInodeInfo *cifsi = inode; |
674 | 675 | ||
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 6df9dadba647..068ef51edbf7 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -580,6 +580,12 @@ typedef union smb_com_session_setup_andx { | |||
580 | 580 | ||
581 | /* format of NLTMv2 Response ie "case sensitive password" hash when NTLMv2 */ | 581 | /* format of NLTMv2 Response ie "case sensitive password" hash when NTLMv2 */ |
582 | 582 | ||
583 | #define NTLMSSP_SERVER_TYPE 1 | ||
584 | #define NTLMSSP_DOMAIN_TYPE 2 | ||
585 | #define NTLMSSP_FQ_DOMAIN_TYPE 3 | ||
586 | #define NTLMSSP_DNS_DOMAIN_TYPE 4 | ||
587 | #define NTLMSSP_DNS_PARENT_TYPE 5 | ||
588 | |||
583 | struct ntlmssp2_name { | 589 | struct ntlmssp2_name { |
584 | __le16 type; | 590 | __le16 type; |
585 | __le16 length; | 591 | __le16 length; |
@@ -593,7 +599,7 @@ struct ntlmv2_resp { | |||
593 | __le64 time; | 599 | __le64 time; |
594 | __u64 client_chal; /* random */ | 600 | __u64 client_chal; /* random */ |
595 | __u32 reserved2; | 601 | __u32 reserved2; |
596 | struct ntlmssp2_name names[1]; | 602 | struct ntlmssp2_name names[2]; |
597 | /* array of name entries could follow ending in minimum 4 byte struct */ | 603 | /* array of name entries could follow ending in minimum 4 byte struct */ |
598 | } __attribute__((packed)); | 604 | } __attribute__((packed)); |
599 | 605 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 098790eb2aa1..472e33e0f3cf 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -4876,7 +4876,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, | |||
4876 | } else { | 4876 | } else { |
4877 | /* Add file to outstanding requests */ | 4877 | /* Add file to outstanding requests */ |
4878 | /* BB change to kmem cache alloc */ | 4878 | /* BB change to kmem cache alloc */ |
4879 | dnotify_req = (struct dir_notify_req *) kmalloc( | 4879 | dnotify_req = kmalloc( |
4880 | sizeof(struct dir_notify_req), | 4880 | sizeof(struct dir_notify_req), |
4881 | GFP_KERNEL); | 4881 | GFP_KERNEL); |
4882 | if(dnotify_req) { | 4882 | if(dnotify_req) { |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 71f77914ce93..2caca06b4bae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/completion.h> | 32 | #include <linux/completion.h> |
33 | #include <linux/pagevec.h> | 33 | #include <linux/pagevec.h> |
34 | #include <linux/freezer.h> | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
36 | #include "cifspdu.h" | 37 | #include "cifspdu.h" |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index d91a3d44e9e3..da12b482ebe5 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c | |||
@@ -83,10 +83,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
83 | return 0; | 83 | return 0; |
84 | 84 | ||
85 | xid = GetXid(); | 85 | xid = GetXid(); |
86 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 86 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
87 | pTcon = cifs_sb->tcon; | 87 | pTcon = cifs_sb->tcon; |
88 | 88 | ||
89 | full_path = build_path_from_dentry(file->f_dentry); | 89 | full_path = build_path_from_dentry(file->f_path.dentry); |
90 | 90 | ||
91 | if(full_path == NULL) { | 91 | if(full_path == NULL) { |
92 | rc = -ENOMEM; | 92 | rc = -ENOMEM; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 2436ed8fc840..8a49b2e77d37 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/pagevec.h> | 29 | #include <linux/pagevec.h> |
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
31 | #include <linux/writeback.h> | 31 | #include <linux/writeback.h> |
32 | #include <linux/task_io_accounting_ops.h> | ||
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
33 | #include <asm/div64.h> | 34 | #include <asm/div64.h> |
34 | #include "cifsfs.h" | 35 | #include "cifsfs.h" |
@@ -122,34 +123,34 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
122 | /* if not oplocked, invalidate inode pages if mtime or file | 123 | /* if not oplocked, invalidate inode pages if mtime or file |
123 | size changed */ | 124 | size changed */ |
124 | temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime)); | 125 | temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime)); |
125 | if (timespec_equal(&file->f_dentry->d_inode->i_mtime, &temp) && | 126 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && |
126 | (file->f_dentry->d_inode->i_size == | 127 | (file->f_path.dentry->d_inode->i_size == |
127 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 128 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
128 | cFYI(1, ("inode unchanged on server")); | 129 | cFYI(1, ("inode unchanged on server")); |
129 | } else { | 130 | } else { |
130 | if (file->f_dentry->d_inode->i_mapping) { | 131 | if (file->f_path.dentry->d_inode->i_mapping) { |
131 | /* BB no need to lock inode until after invalidate | 132 | /* BB no need to lock inode until after invalidate |
132 | since namei code should already have it locked? */ | 133 | since namei code should already have it locked? */ |
133 | filemap_write_and_wait(file->f_dentry->d_inode->i_mapping); | 134 | filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); |
134 | } | 135 | } |
135 | cFYI(1, ("invalidating remote inode since open detected it " | 136 | cFYI(1, ("invalidating remote inode since open detected it " |
136 | "changed")); | 137 | "changed")); |
137 | invalidate_remote_inode(file->f_dentry->d_inode); | 138 | invalidate_remote_inode(file->f_path.dentry->d_inode); |
138 | } | 139 | } |
139 | 140 | ||
140 | client_can_cache: | 141 | client_can_cache: |
141 | if (pTcon->ses->capabilities & CAP_UNIX) | 142 | if (pTcon->ses->capabilities & CAP_UNIX) |
142 | rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode, | 143 | rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, |
143 | full_path, inode->i_sb, xid); | 144 | full_path, inode->i_sb, xid); |
144 | else | 145 | else |
145 | rc = cifs_get_inode_info(&file->f_dentry->d_inode, | 146 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, |
146 | full_path, buf, inode->i_sb, xid); | 147 | full_path, buf, inode->i_sb, xid); |
147 | 148 | ||
148 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 149 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
149 | pCifsInode->clientCanCacheAll = TRUE; | 150 | pCifsInode->clientCanCacheAll = TRUE; |
150 | pCifsInode->clientCanCacheRead = TRUE; | 151 | pCifsInode->clientCanCacheRead = TRUE; |
151 | cFYI(1, ("Exclusive Oplock granted on inode %p", | 152 | cFYI(1, ("Exclusive Oplock granted on inode %p", |
152 | file->f_dentry->d_inode)); | 153 | file->f_path.dentry->d_inode)); |
153 | } else if ((*oplock & 0xF) == OPLOCK_READ) | 154 | } else if ((*oplock & 0xF) == OPLOCK_READ) |
154 | pCifsInode->clientCanCacheRead = TRUE; | 155 | pCifsInode->clientCanCacheRead = TRUE; |
155 | 156 | ||
@@ -178,7 +179,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
178 | 179 | ||
179 | if (file->f_flags & O_CREAT) { | 180 | if (file->f_flags & O_CREAT) { |
180 | /* search inode for this file and fill in file->private_data */ | 181 | /* search inode for this file and fill in file->private_data */ |
181 | pCifsInode = CIFS_I(file->f_dentry->d_inode); | 182 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
182 | read_lock(&GlobalSMBSeslock); | 183 | read_lock(&GlobalSMBSeslock); |
183 | list_for_each(tmp, &pCifsInode->openFileList) { | 184 | list_for_each(tmp, &pCifsInode->openFileList) { |
184 | pCifsFile = list_entry(tmp, struct cifsFileInfo, | 185 | pCifsFile = list_entry(tmp, struct cifsFileInfo, |
@@ -206,7 +207,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
206 | } | 207 | } |
207 | } | 208 | } |
208 | 209 | ||
209 | full_path = build_path_from_dentry(file->f_dentry); | 210 | full_path = build_path_from_dentry(file->f_path.dentry); |
210 | if (full_path == NULL) { | 211 | if (full_path == NULL) { |
211 | FreeXid(xid); | 212 | FreeXid(xid); |
212 | return -ENOMEM; | 213 | return -ENOMEM; |
@@ -291,7 +292,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
291 | write_lock(&GlobalSMBSeslock); | 292 | write_lock(&GlobalSMBSeslock); |
292 | list_add(&pCifsFile->tlist, &pTcon->openFileList); | 293 | list_add(&pCifsFile->tlist, &pTcon->openFileList); |
293 | 294 | ||
294 | pCifsInode = CIFS_I(file->f_dentry->d_inode); | 295 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
295 | if (pCifsInode) { | 296 | if (pCifsInode) { |
296 | rc = cifs_open_inode_helper(inode, file, pCifsInode, | 297 | rc = cifs_open_inode_helper(inode, file, pCifsInode, |
297 | pCifsFile, pTcon, | 298 | pCifsFile, pTcon, |
@@ -366,7 +367,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
366 | return 0; | 367 | return 0; |
367 | } | 368 | } |
368 | 369 | ||
369 | if (file->f_dentry == NULL) { | 370 | if (file->f_path.dentry == NULL) { |
370 | up(&pCifsFile->fh_sem); | 371 | up(&pCifsFile->fh_sem); |
371 | cFYI(1, ("failed file reopen, no valid name if dentry freed")); | 372 | cFYI(1, ("failed file reopen, no valid name if dentry freed")); |
372 | FreeXid(xid); | 373 | FreeXid(xid); |
@@ -378,7 +379,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
378 | those that already have the rename sem can end up causing writepage | 379 | those that already have the rename sem can end up causing writepage |
379 | to get called and if the server was down that means we end up here, | 380 | to get called and if the server was down that means we end up here, |
380 | and we can never tell if the caller already has the rename_sem */ | 381 | and we can never tell if the caller already has the rename_sem */ |
381 | full_path = build_path_from_dentry(file->f_dentry); | 382 | full_path = build_path_from_dentry(file->f_path.dentry); |
382 | if (full_path == NULL) { | 383 | if (full_path == NULL) { |
383 | up(&pCifsFile->fh_sem); | 384 | up(&pCifsFile->fh_sem); |
384 | FreeXid(xid); | 385 | FreeXid(xid); |
@@ -444,7 +445,7 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
444 | pCifsInode->clientCanCacheAll = TRUE; | 445 | pCifsInode->clientCanCacheAll = TRUE; |
445 | pCifsInode->clientCanCacheRead = TRUE; | 446 | pCifsInode->clientCanCacheRead = TRUE; |
446 | cFYI(1, ("Exclusive Oplock granted on inode %p", | 447 | cFYI(1, ("Exclusive Oplock granted on inode %p", |
447 | file->f_dentry->d_inode)); | 448 | file->f_path.dentry->d_inode)); |
448 | } else if ((oplock & 0xF) == OPLOCK_READ) { | 449 | } else if ((oplock & 0xF) == OPLOCK_READ) { |
449 | pCifsInode->clientCanCacheRead = TRUE; | 450 | pCifsInode->clientCanCacheRead = TRUE; |
450 | pCifsInode->clientCanCacheAll = FALSE; | 451 | pCifsInode->clientCanCacheAll = FALSE; |
@@ -551,7 +552,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
551 | 552 | ||
552 | if (pCFileStruct) { | 553 | if (pCFileStruct) { |
553 | struct cifsTconInfo *pTcon; | 554 | struct cifsTconInfo *pTcon; |
554 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 555 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
555 | 556 | ||
556 | pTcon = cifs_sb->tcon; | 557 | pTcon = cifs_sb->tcon; |
557 | 558 | ||
@@ -664,7 +665,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
664 | } else | 665 | } else |
665 | cFYI(1, ("Unknown type of lock")); | 666 | cFYI(1, ("Unknown type of lock")); |
666 | 667 | ||
667 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 668 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
668 | pTcon = cifs_sb->tcon; | 669 | pTcon = cifs_sb->tcon; |
669 | 670 | ||
670 | if (file->private_data == NULL) { | 671 | if (file->private_data == NULL) { |
@@ -791,10 +792,10 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
791 | int xid, long_op; | 792 | int xid, long_op; |
792 | struct cifsFileInfo *open_file; | 793 | struct cifsFileInfo *open_file; |
793 | 794 | ||
794 | if (file->f_dentry == NULL) | 795 | if (file->f_path.dentry == NULL) |
795 | return -EBADF; | 796 | return -EBADF; |
796 | 797 | ||
797 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 798 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
798 | if (cifs_sb == NULL) | 799 | if (cifs_sb == NULL) |
799 | return -EBADF; | 800 | return -EBADF; |
800 | 801 | ||
@@ -802,7 +803,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
802 | 803 | ||
803 | /* cFYI(1, | 804 | /* cFYI(1, |
804 | (" write %d bytes to offset %lld of %s", write_size, | 805 | (" write %d bytes to offset %lld of %s", write_size, |
805 | *poffset, file->f_dentry->d_name.name)); */ | 806 | *poffset, file->f_path.dentry->d_name.name)); */ |
806 | 807 | ||
807 | if (file->private_data == NULL) | 808 | if (file->private_data == NULL) |
808 | return -EBADF; | 809 | return -EBADF; |
@@ -810,12 +811,12 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
810 | open_file = (struct cifsFileInfo *) file->private_data; | 811 | open_file = (struct cifsFileInfo *) file->private_data; |
811 | 812 | ||
812 | xid = GetXid(); | 813 | xid = GetXid(); |
813 | if (file->f_dentry->d_inode == NULL) { | 814 | if (file->f_path.dentry->d_inode == NULL) { |
814 | FreeXid(xid); | 815 | FreeXid(xid); |
815 | return -EBADF; | 816 | return -EBADF; |
816 | } | 817 | } |
817 | 818 | ||
818 | if (*poffset > file->f_dentry->d_inode->i_size) | 819 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
819 | long_op = 2; /* writes past end of file can take a long time */ | 820 | long_op = 2; /* writes past end of file can take a long time */ |
820 | else | 821 | else |
821 | long_op = 1; | 822 | long_op = 1; |
@@ -840,8 +841,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
840 | return -EBADF; | 841 | return -EBADF; |
841 | } | 842 | } |
842 | if (open_file->invalidHandle) { | 843 | if (open_file->invalidHandle) { |
843 | if ((file->f_dentry == NULL) || | 844 | if ((file->f_path.dentry == NULL) || |
844 | (file->f_dentry->d_inode == NULL)) { | 845 | (file->f_path.dentry->d_inode == NULL)) { |
845 | FreeXid(xid); | 846 | FreeXid(xid); |
846 | return total_written; | 847 | return total_written; |
847 | } | 848 | } |
@@ -849,7 +850,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
849 | filemap_fdatawait from here so tell | 850 | filemap_fdatawait from here so tell |
850 | reopen_file not to flush data to server | 851 | reopen_file not to flush data to server |
851 | now */ | 852 | now */ |
852 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 853 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, |
853 | file, FALSE); | 854 | file, FALSE); |
854 | if (rc != 0) | 855 | if (rc != 0) |
855 | break; | 856 | break; |
@@ -878,17 +879,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
878 | cifs_stats_bytes_written(pTcon, total_written); | 879 | cifs_stats_bytes_written(pTcon, total_written); |
879 | 880 | ||
880 | /* since the write may have blocked check these pointers again */ | 881 | /* since the write may have blocked check these pointers again */ |
881 | if (file->f_dentry) { | 882 | if (file->f_path.dentry) { |
882 | if (file->f_dentry->d_inode) { | 883 | if (file->f_path.dentry->d_inode) { |
883 | struct inode *inode = file->f_dentry->d_inode; | 884 | struct inode *inode = file->f_path.dentry->d_inode; |
884 | inode->i_ctime = inode->i_mtime = | 885 | inode->i_ctime = inode->i_mtime = |
885 | current_fs_time(inode->i_sb); | 886 | current_fs_time(inode->i_sb); |
886 | if (total_written > 0) { | 887 | if (total_written > 0) { |
887 | if (*poffset > file->f_dentry->d_inode->i_size) | 888 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
888 | i_size_write(file->f_dentry->d_inode, | 889 | i_size_write(file->f_path.dentry->d_inode, |
889 | *poffset); | 890 | *poffset); |
890 | } | 891 | } |
891 | mark_inode_dirty_sync(file->f_dentry->d_inode); | 892 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); |
892 | } | 893 | } |
893 | } | 894 | } |
894 | FreeXid(xid); | 895 | FreeXid(xid); |
@@ -906,17 +907,17 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
906 | int xid, long_op; | 907 | int xid, long_op; |
907 | struct cifsFileInfo *open_file; | 908 | struct cifsFileInfo *open_file; |
908 | 909 | ||
909 | if (file->f_dentry == NULL) | 910 | if (file->f_path.dentry == NULL) |
910 | return -EBADF; | 911 | return -EBADF; |
911 | 912 | ||
912 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 913 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
913 | if (cifs_sb == NULL) | 914 | if (cifs_sb == NULL) |
914 | return -EBADF; | 915 | return -EBADF; |
915 | 916 | ||
916 | pTcon = cifs_sb->tcon; | 917 | pTcon = cifs_sb->tcon; |
917 | 918 | ||
918 | cFYI(1,("write %zd bytes to offset %lld of %s", write_size, | 919 | cFYI(1,("write %zd bytes to offset %lld of %s", write_size, |
919 | *poffset, file->f_dentry->d_name.name)); | 920 | *poffset, file->f_path.dentry->d_name.name)); |
920 | 921 | ||
921 | if (file->private_data == NULL) | 922 | if (file->private_data == NULL) |
922 | return -EBADF; | 923 | return -EBADF; |
@@ -924,12 +925,12 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
924 | open_file = (struct cifsFileInfo *)file->private_data; | 925 | open_file = (struct cifsFileInfo *)file->private_data; |
925 | 926 | ||
926 | xid = GetXid(); | 927 | xid = GetXid(); |
927 | if (file->f_dentry->d_inode == NULL) { | 928 | if (file->f_path.dentry->d_inode == NULL) { |
928 | FreeXid(xid); | 929 | FreeXid(xid); |
929 | return -EBADF; | 930 | return -EBADF; |
930 | } | 931 | } |
931 | 932 | ||
932 | if (*poffset > file->f_dentry->d_inode->i_size) | 933 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
933 | long_op = 2; /* writes past end of file can take a long time */ | 934 | long_op = 2; /* writes past end of file can take a long time */ |
934 | else | 935 | else |
935 | long_op = 1; | 936 | long_op = 1; |
@@ -955,8 +956,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
955 | return -EBADF; | 956 | return -EBADF; |
956 | } | 957 | } |
957 | if (open_file->invalidHandle) { | 958 | if (open_file->invalidHandle) { |
958 | if ((file->f_dentry == NULL) || | 959 | if ((file->f_path.dentry == NULL) || |
959 | (file->f_dentry->d_inode == NULL)) { | 960 | (file->f_path.dentry->d_inode == NULL)) { |
960 | FreeXid(xid); | 961 | FreeXid(xid); |
961 | return total_written; | 962 | return total_written; |
962 | } | 963 | } |
@@ -964,7 +965,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
964 | filemap_fdatawait from here so tell | 965 | filemap_fdatawait from here so tell |
965 | reopen_file not to flush data to | 966 | reopen_file not to flush data to |
966 | server now */ | 967 | server now */ |
967 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 968 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, |
968 | file, FALSE); | 969 | file, FALSE); |
969 | if (rc != 0) | 970 | if (rc != 0) |
970 | break; | 971 | break; |
@@ -1011,16 +1012,16 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
1011 | cifs_stats_bytes_written(pTcon, total_written); | 1012 | cifs_stats_bytes_written(pTcon, total_written); |
1012 | 1013 | ||
1013 | /* since the write may have blocked check these pointers again */ | 1014 | /* since the write may have blocked check these pointers again */ |
1014 | if (file->f_dentry) { | 1015 | if (file->f_path.dentry) { |
1015 | if (file->f_dentry->d_inode) { | 1016 | if (file->f_path.dentry->d_inode) { |
1016 | file->f_dentry->d_inode->i_ctime = | 1017 | file->f_path.dentry->d_inode->i_ctime = |
1017 | file->f_dentry->d_inode->i_mtime = CURRENT_TIME; | 1018 | file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME; |
1018 | if (total_written > 0) { | 1019 | if (total_written > 0) { |
1019 | if (*poffset > file->f_dentry->d_inode->i_size) | 1020 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
1020 | i_size_write(file->f_dentry->d_inode, | 1021 | i_size_write(file->f_path.dentry->d_inode, |
1021 | *poffset); | 1022 | *poffset); |
1022 | } | 1023 | } |
1023 | mark_inode_dirty_sync(file->f_dentry->d_inode); | 1024 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); |
1024 | } | 1025 | } |
1025 | } | 1026 | } |
1026 | FreeXid(xid); | 1027 | FreeXid(xid); |
@@ -1244,14 +1245,21 @@ retry: | |||
1244 | wait_on_page_writeback(page); | 1245 | wait_on_page_writeback(page); |
1245 | 1246 | ||
1246 | if (PageWriteback(page) || | 1247 | if (PageWriteback(page) || |
1247 | !test_clear_page_dirty(page)) { | 1248 | !clear_page_dirty_for_io(page)) { |
1248 | unlock_page(page); | 1249 | unlock_page(page); |
1249 | break; | 1250 | break; |
1250 | } | 1251 | } |
1251 | 1252 | ||
1253 | /* | ||
1254 | * This actually clears the dirty bit in the radix tree. | ||
1255 | * See cifs_writepage() for more commentary. | ||
1256 | */ | ||
1257 | set_page_writeback(page); | ||
1258 | |||
1252 | if (page_offset(page) >= mapping->host->i_size) { | 1259 | if (page_offset(page) >= mapping->host->i_size) { |
1253 | done = 1; | 1260 | done = 1; |
1254 | unlock_page(page); | 1261 | unlock_page(page); |
1262 | end_page_writeback(page); | ||
1255 | break; | 1263 | break; |
1256 | } | 1264 | } |
1257 | 1265 | ||
@@ -1315,6 +1323,7 @@ retry: | |||
1315 | SetPageError(page); | 1323 | SetPageError(page); |
1316 | kunmap(page); | 1324 | kunmap(page); |
1317 | unlock_page(page); | 1325 | unlock_page(page); |
1326 | end_page_writeback(page); | ||
1318 | page_cache_release(page); | 1327 | page_cache_release(page); |
1319 | } | 1328 | } |
1320 | if ((wbc->nr_to_write -= n_iov) <= 0) | 1329 | if ((wbc->nr_to_write -= n_iov) <= 0) |
@@ -1351,11 +1360,23 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc) | |||
1351 | if (!PageUptodate(page)) { | 1360 | if (!PageUptodate(page)) { |
1352 | cFYI(1, ("ppw - page not up to date")); | 1361 | cFYI(1, ("ppw - page not up to date")); |
1353 | } | 1362 | } |
1354 | 1363 | ||
1364 | /* | ||
1365 | * Set the "writeback" flag, and clear "dirty" in the radix tree. | ||
1366 | * | ||
1367 | * A writepage() implementation always needs to do either this, | ||
1368 | * or re-dirty the page with "redirty_page_for_writepage()" in | ||
1369 | * the case of a failure. | ||
1370 | * | ||
1371 | * Just unlocking the page will cause the radix tree tag-bits | ||
1372 | * to fail to update with the state of the page correctly. | ||
1373 | */ | ||
1374 | set_page_writeback(page); | ||
1355 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); | 1375 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); |
1356 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ | 1376 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ |
1357 | unlock_page(page); | 1377 | unlock_page(page); |
1358 | page_cache_release(page); | 1378 | end_page_writeback(page); |
1379 | page_cache_release(page); | ||
1359 | FreeXid(xid); | 1380 | FreeXid(xid); |
1360 | return rc; | 1381 | return rc; |
1361 | } | 1382 | } |
@@ -1384,7 +1405,7 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1384 | if ((open_file->invalidHandle) && | 1405 | if ((open_file->invalidHandle) && |
1385 | (!open_file->closePend)) { | 1406 | (!open_file->closePend)) { |
1386 | rc = cifs_reopen_file( | 1407 | rc = cifs_reopen_file( |
1387 | file->f_dentry->d_inode, file); | 1408 | file->f_path.dentry->d_inode, file); |
1388 | if (rc != 0) | 1409 | if (rc != 0) |
1389 | break; | 1410 | break; |
1390 | } | 1411 | } |
@@ -1434,7 +1455,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1434 | { | 1455 | { |
1435 | int xid; | 1456 | int xid; |
1436 | int rc = 0; | 1457 | int rc = 0; |
1437 | struct inode *inode = file->f_dentry->d_inode; | 1458 | struct inode *inode = file->f_path.dentry->d_inode; |
1438 | 1459 | ||
1439 | xid = GetXid(); | 1460 | xid = GetXid(); |
1440 | 1461 | ||
@@ -1482,7 +1503,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1482 | */ | 1503 | */ |
1483 | int cifs_flush(struct file *file, fl_owner_t id) | 1504 | int cifs_flush(struct file *file, fl_owner_t id) |
1484 | { | 1505 | { |
1485 | struct inode * inode = file->f_dentry->d_inode; | 1506 | struct inode * inode = file->f_path.dentry->d_inode; |
1486 | int rc = 0; | 1507 | int rc = 0; |
1487 | 1508 | ||
1488 | /* Rather than do the steps manually: | 1509 | /* Rather than do the steps manually: |
@@ -1519,7 +1540,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1519 | struct smb_com_read_rsp *pSMBr; | 1540 | struct smb_com_read_rsp *pSMBr; |
1520 | 1541 | ||
1521 | xid = GetXid(); | 1542 | xid = GetXid(); |
1522 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1543 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
1523 | pTcon = cifs_sb->tcon; | 1544 | pTcon = cifs_sb->tcon; |
1524 | 1545 | ||
1525 | if (file->private_data == NULL) { | 1546 | if (file->private_data == NULL) { |
@@ -1542,7 +1563,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1542 | int buf_type = CIFS_NO_BUFFER; | 1563 | int buf_type = CIFS_NO_BUFFER; |
1543 | if ((open_file->invalidHandle) && | 1564 | if ((open_file->invalidHandle) && |
1544 | (!open_file->closePend)) { | 1565 | (!open_file->closePend)) { |
1545 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 1566 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, |
1546 | file, TRUE); | 1567 | file, TRUE); |
1547 | if (rc != 0) | 1568 | if (rc != 0) |
1548 | break; | 1569 | break; |
@@ -1601,7 +1622,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1601 | int buf_type = CIFS_NO_BUFFER; | 1622 | int buf_type = CIFS_NO_BUFFER; |
1602 | 1623 | ||
1603 | xid = GetXid(); | 1624 | xid = GetXid(); |
1604 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1625 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
1605 | pTcon = cifs_sb->tcon; | 1626 | pTcon = cifs_sb->tcon; |
1606 | 1627 | ||
1607 | if (file->private_data == NULL) { | 1628 | if (file->private_data == NULL) { |
@@ -1629,7 +1650,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1629 | while (rc == -EAGAIN) { | 1650 | while (rc == -EAGAIN) { |
1630 | if ((open_file->invalidHandle) && | 1651 | if ((open_file->invalidHandle) && |
1631 | (!open_file->closePend)) { | 1652 | (!open_file->closePend)) { |
1632 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 1653 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, |
1633 | file, TRUE); | 1654 | file, TRUE); |
1634 | if (rc != 0) | 1655 | if (rc != 0) |
1635 | break; | 1656 | break; |
@@ -1658,7 +1679,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1658 | 1679 | ||
1659 | int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | 1680 | int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) |
1660 | { | 1681 | { |
1661 | struct dentry *dentry = file->f_dentry; | 1682 | struct dentry *dentry = file->f_path.dentry; |
1662 | int rc, xid; | 1683 | int rc, xid; |
1663 | 1684 | ||
1664 | xid = GetXid(); | 1685 | xid = GetXid(); |
@@ -1744,7 +1765,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1744 | return -EBADF; | 1765 | return -EBADF; |
1745 | } | 1766 | } |
1746 | open_file = (struct cifsFileInfo *)file->private_data; | 1767 | open_file = (struct cifsFileInfo *)file->private_data; |
1747 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1768 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
1748 | pTcon = cifs_sb->tcon; | 1769 | pTcon = cifs_sb->tcon; |
1749 | 1770 | ||
1750 | pagevec_init(&lru_pvec, 0); | 1771 | pagevec_init(&lru_pvec, 0); |
@@ -1786,7 +1807,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1786 | while (rc == -EAGAIN) { | 1807 | while (rc == -EAGAIN) { |
1787 | if ((open_file->invalidHandle) && | 1808 | if ((open_file->invalidHandle) && |
1788 | (!open_file->closePend)) { | 1809 | (!open_file->closePend)) { |
1789 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 1810 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, |
1790 | file, TRUE); | 1811 | file, TRUE); |
1791 | if (rc != 0) | 1812 | if (rc != 0) |
1792 | break; | 1813 | break; |
@@ -1812,6 +1833,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1812 | cFYI(1, ("Read error in readpages: %d", rc)); | 1833 | cFYI(1, ("Read error in readpages: %d", rc)); |
1813 | break; | 1834 | break; |
1814 | } else if (bytes_read > 0) { | 1835 | } else if (bytes_read > 0) { |
1836 | task_io_account_read(bytes_read); | ||
1815 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 1837 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
1816 | cifs_copy_cache_pages(mapping, page_list, bytes_read, | 1838 | cifs_copy_cache_pages(mapping, page_list, bytes_read, |
1817 | smb_read_data + 4 /* RFC1001 hdr */ + | 1839 | smb_read_data + 4 /* RFC1001 hdr */ + |
@@ -1880,8 +1902,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
1880 | else | 1902 | else |
1881 | cFYI(1, ("Bytes read %d",rc)); | 1903 | cFYI(1, ("Bytes read %d",rc)); |
1882 | 1904 | ||
1883 | file->f_dentry->d_inode->i_atime = | 1905 | file->f_path.dentry->d_inode->i_atime = |
1884 | current_fs_time(file->f_dentry->d_inode->i_sb); | 1906 | current_fs_time(file->f_path.dentry->d_inode->i_sb); |
1885 | 1907 | ||
1886 | if (PAGE_CACHE_SIZE > rc) | 1908 | if (PAGE_CACHE_SIZE > rc) |
1887 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); | 1909 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 1ad8c9fcc742..c4fa91b8b62f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -318,6 +318,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
318 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 318 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
319 | char *tmp_path; | 319 | char *tmp_path; |
320 | char *buf = NULL; | 320 | char *buf = NULL; |
321 | int adjustTZ = FALSE; | ||
321 | 322 | ||
322 | pTcon = cifs_sb->tcon; | 323 | pTcon = cifs_sb->tcon; |
323 | cFYI(1,("Getting info on %s", search_path)); | 324 | cFYI(1,("Getting info on %s", search_path)); |
@@ -348,6 +349,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
348 | pfindData, cifs_sb->local_nls, | 349 | pfindData, cifs_sb->local_nls, |
349 | cifs_sb->mnt_cifs_flags & | 350 | cifs_sb->mnt_cifs_flags & |
350 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 351 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
352 | adjustTZ = TRUE; | ||
351 | } | 353 | } |
352 | 354 | ||
353 | } | 355 | } |
@@ -444,6 +446,10 @@ int cifs_get_inode_info(struct inode **pinode, | |||
444 | inode->i_ctime = | 446 | inode->i_ctime = |
445 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 447 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
446 | cFYI(0, ("Attributes came in as 0x%x", attr)); | 448 | cFYI(0, ("Attributes came in as 0x%x", attr)); |
449 | if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { | ||
450 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; | ||
451 | inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; | ||
452 | } | ||
447 | 453 | ||
448 | /* set default mode. will override for dirs below */ | 454 | /* set default mode. will override for dirs below */ |
449 | if (atomic_read(&cifsInfo->inUse) == 0) | 455 | if (atomic_read(&cifsInfo->inUse) == 0) |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 0bee8b7e521a..8e259969354b 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -69,17 +69,30 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
69 | rc = -EOPNOTSUPP; | 69 | rc = -EOPNOTSUPP; |
70 | } | 70 | } |
71 | 71 | ||
72 | /* if (!rc) */ | 72 | d_drop(direntry); /* force new lookup from server of target */ |
73 | { | 73 | |
74 | /* renew_parental_timestamps(old_file); | 74 | /* if source file is cached (oplocked) revalidate will not go to server |
75 | inode->i_nlink++; | 75 | until the file is closed or oplock broken so update nlinks locally */ |
76 | mark_inode_dirty(inode); | 76 | if(old_file->d_inode) { |
77 | d_instantiate(direntry, inode); */ | 77 | cifsInode = CIFS_I(old_file->d_inode); |
78 | /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ | 78 | if(rc == 0) { |
79 | old_file->d_inode->i_nlink++; | ||
80 | old_file->d_inode->i_ctime = CURRENT_TIME; | ||
81 | /* parent dir timestamps will update from srv | ||
82 | within a second, would it really be worth it | ||
83 | to set the parent dir cifs inode time to zero | ||
84 | to force revalidate (faster) for it too? */ | ||
85 | } | ||
86 | /* if not oplocked will force revalidate to get info | ||
87 | on source file from srv */ | ||
88 | cifsInode->time = 0; | ||
89 | |||
90 | /* Will update parent dir timestamps from srv within a second. | ||
91 | Would it really be worth it to set the parent dir (cifs | ||
92 | inode) time field to zero to force revalidate on parent | ||
93 | directory faster ie | ||
94 | CIFS_I(inode)->time = 0; */ | ||
79 | } | 95 | } |
80 | d_drop(direntry); /* force new lookup from server */ | ||
81 | cifsInode = CIFS_I(old_file->d_inode); | ||
82 | cifsInode->time = 0; /* will force revalidate to go get info when needed */ | ||
83 | 96 | ||
84 | cifs_hl_exit: | 97 | cifs_hl_exit: |
85 | kfree(fromName); | 98 | kfree(fromName); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index bbc9cd34b6ea..aedf683f011f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -153,7 +153,7 @@ cifs_buf_get(void) | |||
153 | albeit slightly larger than necessary and maxbuffersize | 153 | albeit slightly larger than necessary and maxbuffersize |
154 | defaults to this and can not be bigger */ | 154 | defaults to this and can not be bigger */ |
155 | ret_buf = | 155 | ret_buf = |
156 | (struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS); | 156 | (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); |
157 | 157 | ||
158 | /* clear the first few header bytes */ | 158 | /* clear the first few header bytes */ |
159 | /* for most paths, more is cleared in header_assemble */ | 159 | /* for most paths, more is cleared in header_assemble */ |
@@ -192,7 +192,7 @@ cifs_small_buf_get(void) | |||
192 | albeit slightly larger than necessary and maxbuffersize | 192 | albeit slightly larger than necessary and maxbuffersize |
193 | defaults to this and can not be bigger */ | 193 | defaults to this and can not be bigger */ |
194 | ret_buf = | 194 | ret_buf = |
195 | (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, SLAB_KERNEL | SLAB_NOFS); | 195 | (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); |
196 | if (ret_buf) { | 196 | if (ret_buf) { |
197 | /* No need to clear memory here, cleared in header assemble */ | 197 | /* No need to clear memory here, cleared in header assemble */ |
198 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ | 198 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index ed18c3965f7b..99dfb5337e31 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -68,30 +68,30 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
68 | int rc = 0; | 68 | int rc = 0; |
69 | 69 | ||
70 | cFYI(1, ("For %s", qstring->name)); | 70 | cFYI(1, ("For %s", qstring->name)); |
71 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 71 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
72 | pTcon = cifs_sb->tcon; | 72 | pTcon = cifs_sb->tcon; |
73 | 73 | ||
74 | qstring->hash = full_name_hash(qstring->name, qstring->len); | 74 | qstring->hash = full_name_hash(qstring->name, qstring->len); |
75 | tmp_dentry = d_lookup(file->f_dentry, qstring); | 75 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); |
76 | if (tmp_dentry) { | 76 | if (tmp_dentry) { |
77 | cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); | 77 | cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); |
78 | *ptmp_inode = tmp_dentry->d_inode; | 78 | *ptmp_inode = tmp_dentry->d_inode; |
79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ | 79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ |
80 | if(*ptmp_inode == NULL) { | 80 | if(*ptmp_inode == NULL) { |
81 | *ptmp_inode = new_inode(file->f_dentry->d_sb); | 81 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); |
82 | if(*ptmp_inode == NULL) | 82 | if(*ptmp_inode == NULL) |
83 | return rc; | 83 | return rc; |
84 | rc = 1; | 84 | rc = 1; |
85 | } | 85 | } |
86 | } else { | 86 | } else { |
87 | tmp_dentry = d_alloc(file->f_dentry, qstring); | 87 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); |
88 | if(tmp_dentry == NULL) { | 88 | if(tmp_dentry == NULL) { |
89 | cERROR(1,("Failed allocating dentry")); | 89 | cERROR(1,("Failed allocating dentry")); |
90 | *ptmp_inode = NULL; | 90 | *ptmp_inode = NULL; |
91 | return rc; | 91 | return rc; |
92 | } | 92 | } |
93 | 93 | ||
94 | *ptmp_inode = new_inode(file->f_dentry->d_sb); | 94 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); |
95 | if (pTcon->nocase) | 95 | if (pTcon->nocase) |
96 | tmp_dentry->d_op = &cifs_ci_dentry_ops; | 96 | tmp_dentry->d_op = &cifs_ci_dentry_ops; |
97 | else | 97 | else |
@@ -432,10 +432,10 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
432 | cifsFile->invalidHandle = TRUE; | 432 | cifsFile->invalidHandle = TRUE; |
433 | cifsFile->srch_inf.endOfSearch = FALSE; | 433 | cifsFile->srch_inf.endOfSearch = FALSE; |
434 | 434 | ||
435 | if(file->f_dentry == NULL) | 435 | if(file->f_path.dentry == NULL) |
436 | return -ENOENT; | 436 | return -ENOENT; |
437 | 437 | ||
438 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 438 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
439 | if(cifs_sb == NULL) | 439 | if(cifs_sb == NULL) |
440 | return -EINVAL; | 440 | return -EINVAL; |
441 | 441 | ||
@@ -443,7 +443,7 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
443 | if(pTcon == NULL) | 443 | if(pTcon == NULL) |
444 | return -EINVAL; | 444 | return -EINVAL; |
445 | 445 | ||
446 | full_path = build_path_from_dentry(file->f_dentry); | 446 | full_path = build_path_from_dentry(file->f_path.dentry); |
447 | 447 | ||
448 | if(full_path == NULL) { | 448 | if(full_path == NULL) { |
449 | return -ENOMEM; | 449 | return -ENOMEM; |
@@ -609,10 +609,10 @@ static int is_dir_changed(struct file * file) | |||
609 | struct inode * inode; | 609 | struct inode * inode; |
610 | struct cifsInodeInfo *cifsInfo; | 610 | struct cifsInodeInfo *cifsInfo; |
611 | 611 | ||
612 | if(file->f_dentry == NULL) | 612 | if(file->f_path.dentry == NULL) |
613 | return 0; | 613 | return 0; |
614 | 614 | ||
615 | inode = file->f_dentry->d_inode; | 615 | inode = file->f_path.dentry->d_inode; |
616 | 616 | ||
617 | if(inode == NULL) | 617 | if(inode == NULL) |
618 | return 0; | 618 | return 0; |
@@ -839,7 +839,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
839 | if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) | 839 | if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) |
840 | return -ENOENT; | 840 | return -ENOENT; |
841 | 841 | ||
842 | if(file->f_dentry == NULL) | 842 | if(file->f_path.dentry == NULL) |
843 | return -ENOENT; | 843 | return -ENOENT; |
844 | 844 | ||
845 | rc = cifs_entry_is_dot(pfindEntry,pCifsF); | 845 | rc = cifs_entry_is_dot(pfindEntry,pCifsF); |
@@ -847,7 +847,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
847 | if(rc != 0) | 847 | if(rc != 0) |
848 | return 0; | 848 | return 0; |
849 | 849 | ||
850 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 850 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
851 | 851 | ||
852 | qstring.name = scratch_buf; | 852 | qstring.name = scratch_buf; |
853 | rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, | 853 | rc = cifs_get_name_from_search_buf(&qstring,pfindEntry, |
@@ -985,12 +985,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
985 | 985 | ||
986 | xid = GetXid(); | 986 | xid = GetXid(); |
987 | 987 | ||
988 | if(file->f_dentry == NULL) { | 988 | if(file->f_path.dentry == NULL) { |
989 | FreeXid(xid); | 989 | FreeXid(xid); |
990 | return -EIO; | 990 | return -EIO; |
991 | } | 991 | } |
992 | 992 | ||
993 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 993 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
994 | pTcon = cifs_sb->tcon; | 994 | pTcon = cifs_sb->tcon; |
995 | if(pTcon == NULL) | 995 | if(pTcon == NULL) |
996 | return -EINVAL; | 996 | return -EINVAL; |
@@ -998,7 +998,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
998 | switch ((int) file->f_pos) { | 998 | switch ((int) file->f_pos) { |
999 | case 0: | 999 | case 0: |
1000 | if (filldir(direntry, ".", 1, file->f_pos, | 1000 | if (filldir(direntry, ".", 1, file->f_pos, |
1001 | file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { | 1001 | file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) { |
1002 | cERROR(1, ("Filldir for current dir failed")); | 1002 | cERROR(1, ("Filldir for current dir failed")); |
1003 | rc = -ENOMEM; | 1003 | rc = -ENOMEM; |
1004 | break; | 1004 | break; |
@@ -1006,7 +1006,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
1006 | file->f_pos++; | 1006 | file->f_pos++; |
1007 | case 1: | 1007 | case 1: |
1008 | if (filldir(direntry, "..", 2, file->f_pos, | 1008 | if (filldir(direntry, "..", 2, file->f_pos, |
1009 | file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { | 1009 | file->f_path.dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { |
1010 | cERROR(1, ("Filldir for parent dir failed")); | 1010 | cERROR(1, ("Filldir for parent dir failed")); |
1011 | rc = -ENOMEM; | 1011 | rc = -ENOMEM; |
1012 | break; | 1012 | break; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 48d47b46b1fb..f80007eaebf4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "cifs_debug.h" | 34 | #include "cifs_debug.h" |
35 | 35 | ||
36 | extern mempool_t *cifs_mid_poolp; | 36 | extern mempool_t *cifs_mid_poolp; |
37 | extern kmem_cache_t *cifs_oplock_cachep; | 37 | extern struct kmem_cache *cifs_oplock_cachep; |
38 | 38 | ||
39 | static struct mid_q_entry * | 39 | static struct mid_q_entry * |
40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | 40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) |
@@ -51,7 +51,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, | 53 | temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, |
54 | SLAB_KERNEL | SLAB_NOFS); | 54 | GFP_KERNEL | GFP_NOFS); |
55 | if (temp == NULL) | 55 | if (temp == NULL) |
56 | return temp; | 56 | return temp; |
57 | else { | 57 | else { |
@@ -118,7 +118,7 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) | |||
118 | return NULL; | 118 | return NULL; |
119 | } | 119 | } |
120 | temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, | 120 | temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, |
121 | SLAB_KERNEL); | 121 | GFP_KERNEL); |
122 | if (temp == NULL) | 122 | if (temp == NULL) |
123 | return temp; | 123 | return temp; |
124 | else { | 124 | else { |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 0102b28a15fb..0c6f7f3b3dd7 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -441,7 +441,7 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
441 | /* file operations for directories */ | 441 | /* file operations for directories */ |
442 | int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) | 442 | int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) |
443 | { | 443 | { |
444 | struct dentry *coda_dentry = coda_file->f_dentry; | 444 | struct dentry *coda_dentry = coda_file->f_path.dentry; |
445 | struct coda_file_info *cfi; | 445 | struct coda_file_info *cfi; |
446 | struct file *host_file; | 446 | struct file *host_file; |
447 | struct inode *host_inode; | 447 | struct inode *host_inode; |
@@ -453,7 +453,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) | |||
453 | 453 | ||
454 | coda_vfs_stat.readdir++; | 454 | coda_vfs_stat.readdir++; |
455 | 455 | ||
456 | host_inode = host_file->f_dentry->d_inode; | 456 | host_inode = host_file->f_path.dentry->d_inode; |
457 | mutex_lock(&host_inode->i_mutex); | 457 | mutex_lock(&host_inode->i_mutex); |
458 | host_file->f_pos = coda_file->f_pos; | 458 | host_file->f_pos = coda_file->f_pos; |
459 | 459 | ||
@@ -544,14 +544,14 @@ static int coda_venus_readdir(struct file *filp, filldir_t filldir, | |||
544 | /* catch truncated reads */ | 544 | /* catch truncated reads */ |
545 | if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) { | 545 | if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) { |
546 | printk("coda_venus_readdir: short read: %ld\n", | 546 | printk("coda_venus_readdir: short read: %ld\n", |
547 | filp->f_dentry->d_inode->i_ino); | 547 | filp->f_path.dentry->d_inode->i_ino); |
548 | ret = -EBADF; | 548 | ret = -EBADF; |
549 | break; | 549 | break; |
550 | } | 550 | } |
551 | /* validate whether the directory file actually makes sense */ | 551 | /* validate whether the directory file actually makes sense */ |
552 | if (vdir->d_reclen < vdir_size + vdir->d_namlen) { | 552 | if (vdir->d_reclen < vdir_size + vdir->d_namlen) { |
553 | printk("coda_venus_readdir: Invalid dir: %ld\n", | 553 | printk("coda_venus_readdir: Invalid dir: %ld\n", |
554 | filp->f_dentry->d_inode->i_ino); | 554 | filp->f_path.dentry->d_inode->i_ino); |
555 | ret = -EBADF; | 555 | ret = -EBADF; |
556 | break; | 556 | break; |
557 | } | 557 | } |
diff --git a/fs/coda/file.c b/fs/coda/file.c index dbfbcfa5b3c0..5ef2b609ec7d 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -66,7 +66,7 @@ coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count, | |||
66 | static ssize_t | 66 | static ssize_t |
67 | coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos) | 67 | coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos) |
68 | { | 68 | { |
69 | struct inode *host_inode, *coda_inode = coda_file->f_dentry->d_inode; | 69 | struct inode *host_inode, *coda_inode = coda_file->f_path.dentry->d_inode; |
70 | struct coda_file_info *cfi; | 70 | struct coda_file_info *cfi; |
71 | struct file *host_file; | 71 | struct file *host_file; |
72 | ssize_t ret; | 72 | ssize_t ret; |
@@ -78,7 +78,7 @@ coda_file_write(struct file *coda_file, const char __user *buf, size_t count, lo | |||
78 | if (!host_file->f_op || !host_file->f_op->write) | 78 | if (!host_file->f_op || !host_file->f_op->write) |
79 | return -EINVAL; | 79 | return -EINVAL; |
80 | 80 | ||
81 | host_inode = host_file->f_dentry->d_inode; | 81 | host_inode = host_file->f_path.dentry->d_inode; |
82 | mutex_lock(&coda_inode->i_mutex); | 82 | mutex_lock(&coda_inode->i_mutex); |
83 | 83 | ||
84 | ret = host_file->f_op->write(host_file, buf, count, ppos); | 84 | ret = host_file->f_op->write(host_file, buf, count, ppos); |
@@ -106,8 +106,8 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) | |||
106 | if (!host_file->f_op || !host_file->f_op->mmap) | 106 | if (!host_file->f_op || !host_file->f_op->mmap) |
107 | return -ENODEV; | 107 | return -ENODEV; |
108 | 108 | ||
109 | coda_inode = coda_file->f_dentry->d_inode; | 109 | coda_inode = coda_file->f_path.dentry->d_inode; |
110 | host_inode = host_file->f_dentry->d_inode; | 110 | host_inode = host_file->f_path.dentry->d_inode; |
111 | coda_file->f_mapping = host_file->f_mapping; | 111 | coda_file->f_mapping = host_file->f_mapping; |
112 | if (coda_inode->i_mapping == &coda_inode->i_data) | 112 | if (coda_inode->i_mapping == &coda_inode->i_data) |
113 | coda_inode->i_mapping = host_inode->i_mapping; | 113 | coda_inode->i_mapping = host_inode->i_mapping; |
@@ -190,7 +190,7 @@ int coda_flush(struct file *coda_file, fl_owner_t id) | |||
190 | cfi = CODA_FTOC(coda_file); | 190 | cfi = CODA_FTOC(coda_file); |
191 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 191 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
192 | 192 | ||
193 | coda_inode = coda_file->f_dentry->d_inode; | 193 | coda_inode = coda_file->f_path.dentry->d_inode; |
194 | 194 | ||
195 | err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, | 195 | err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, |
196 | coda_file->f_uid); | 196 | coda_file->f_uid); |
@@ -233,7 +233,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) | |||
233 | err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), | 233 | err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), |
234 | coda_flags, coda_file->f_uid); | 234 | coda_flags, coda_file->f_uid); |
235 | 235 | ||
236 | host_inode = cfi->cfi_container->f_dentry->d_inode; | 236 | host_inode = cfi->cfi_container->f_path.dentry->d_inode; |
237 | cii = ITOC(coda_inode); | 237 | cii = ITOC(coda_inode); |
238 | 238 | ||
239 | /* did we mmap this file? */ | 239 | /* did we mmap this file? */ |
@@ -270,7 +270,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) | |||
270 | coda_vfs_stat.fsync++; | 270 | coda_vfs_stat.fsync++; |
271 | 271 | ||
272 | if (host_file->f_op && host_file->f_op->fsync) { | 272 | if (host_file->f_op && host_file->f_op->fsync) { |
273 | host_dentry = host_file->f_dentry; | 273 | host_dentry = host_file->f_path.dentry; |
274 | host_inode = host_dentry->d_inode; | 274 | host_inode = host_dentry->d_inode; |
275 | mutex_lock(&host_inode->i_mutex); | 275 | mutex_lock(&host_inode->i_mutex); |
276 | err = host_file->f_op->fsync(host_file, host_dentry, datasync); | 276 | err = host_file->f_op->fsync(host_file, host_dentry, datasync); |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 88d123321164..01395defed85 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -38,12 +38,12 @@ static void coda_clear_inode(struct inode *); | |||
38 | static void coda_put_super(struct super_block *); | 38 | static void coda_put_super(struct super_block *); |
39 | static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); | 39 | static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); |
40 | 40 | ||
41 | static kmem_cache_t * coda_inode_cachep; | 41 | static struct kmem_cache * coda_inode_cachep; |
42 | 42 | ||
43 | static struct inode *coda_alloc_inode(struct super_block *sb) | 43 | static struct inode *coda_alloc_inode(struct super_block *sb) |
44 | { | 44 | { |
45 | struct coda_inode_info *ei; | 45 | struct coda_inode_info *ei; |
46 | ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, SLAB_KERNEL); | 46 | ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); |
47 | if (!ei) | 47 | if (!ei) |
48 | return NULL; | 48 | return NULL; |
49 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); | 49 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); |
@@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode) | |||
58 | kmem_cache_free(coda_inode_cachep, ITOC(inode)); | 58 | kmem_cache_free(coda_inode_cachep, ITOC(inode)); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 61 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
62 | { | 62 | { |
63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; | 63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; |
64 | 64 | ||
@@ -119,7 +119,7 @@ static int get_device_index(struct coda_mount_data *data) | |||
119 | file = fget(data->fd); | 119 | file = fget(data->fd); |
120 | inode = NULL; | 120 | inode = NULL; |
121 | if(file) | 121 | if(file) |
122 | inode = file->f_dentry->d_inode; | 122 | inode = file->f_path.dentry->d_inode; |
123 | 123 | ||
124 | if(!inode || !S_ISCHR(inode->i_mode) || | 124 | if(!inode || !S_ISCHR(inode->i_mode) || |
125 | imajor(inode) != CODA_PSDEV_MAJOR) { | 125 | imajor(inode) != CODA_PSDEV_MAJOR) { |
diff --git a/fs/compat.c b/fs/compat.c index 8d0a0018a7d2..0ec70e3cee0a 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/personality.h> | 45 | #include <linux/personality.h> |
46 | #include <linux/rwsem.h> | 46 | #include <linux/rwsem.h> |
47 | #include <linux/tsacct_kern.h> | 47 | #include <linux/tsacct_kern.h> |
48 | #include <linux/highmem.h> | ||
49 | #include <linux/poll.h> | ||
48 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
49 | 51 | ||
50 | #include <net/sock.h> /* siocdevprivate_ioctl */ | 52 | #include <net/sock.h> /* siocdevprivate_ioctl */ |
@@ -230,7 +232,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user | |||
230 | file = fget(fd); | 232 | file = fget(fd); |
231 | if (!file) | 233 | if (!file) |
232 | goto out; | 234 | goto out; |
233 | error = vfs_statfs(file->f_dentry, &tmp); | 235 | error = vfs_statfs(file->f_path.dentry, &tmp); |
234 | if (!error) | 236 | if (!error) |
235 | error = put_compat_statfs(buf, &tmp); | 237 | error = put_compat_statfs(buf, &tmp); |
236 | fput(file); | 238 | fput(file); |
@@ -301,7 +303,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c | |||
301 | file = fget(fd); | 303 | file = fget(fd); |
302 | if (!file) | 304 | if (!file) |
303 | goto out; | 305 | goto out; |
304 | error = vfs_statfs(file->f_dentry, &tmp); | 306 | error = vfs_statfs(file->f_path.dentry, &tmp); |
305 | if (!error) | 307 | if (!error) |
306 | error = put_compat_statfs64(buf, &tmp); | 308 | error = put_compat_statfs64(buf, &tmp); |
307 | fput(file); | 309 | fput(file); |
@@ -363,7 +365,7 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd, | |||
363 | /* find the name of the device. */ | 365 | /* find the name of the device. */ |
364 | path = (char *)__get_free_page(GFP_KERNEL); | 366 | path = (char *)__get_free_page(GFP_KERNEL); |
365 | if (path) { | 367 | if (path) { |
366 | fn = d_path(filp->f_dentry, filp->f_vfsmnt, path, PAGE_SIZE); | 368 | fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); |
367 | if (IS_ERR(fn)) | 369 | if (IS_ERR(fn)) |
368 | fn = "?"; | 370 | fn = "?"; |
369 | } | 371 | } |
@@ -414,7 +416,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
414 | case FIBMAP: | 416 | case FIBMAP: |
415 | case FIGETBSZ: | 417 | case FIGETBSZ: |
416 | case FIONREAD: | 418 | case FIONREAD: |
417 | if (S_ISREG(filp->f_dentry->d_inode->i_mode)) | 419 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) |
418 | break; | 420 | break; |
419 | /*FALL THROUGH*/ | 421 | /*FALL THROUGH*/ |
420 | 422 | ||
@@ -436,7 +438,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
436 | goto found_handler; | 438 | goto found_handler; |
437 | } | 439 | } |
438 | 440 | ||
439 | if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) && | 441 | if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) && |
440 | cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { | 442 | cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { |
441 | error = siocdevprivate_ioctl(fd, cmd, arg); | 443 | error = siocdevprivate_ioctl(fd, cmd, arg); |
442 | } else { | 444 | } else { |
@@ -869,7 +871,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
869 | 871 | ||
870 | retval = -EINVAL; | 872 | retval = -EINVAL; |
871 | 873 | ||
872 | if (type_page) { | 874 | if (type_page && data_page) { |
873 | if (!strcmp((char *)type_page, SMBFS_NAME)) { | 875 | if (!strcmp((char *)type_page, SMBFS_NAME)) { |
874 | do_smb_super_data_conv((void *)data_page); | 876 | do_smb_super_data_conv((void *)data_page); |
875 | } else if (!strcmp((char *)type_page, NCPFS_NAME)) { | 877 | } else if (!strcmp((char *)type_page, NCPFS_NAME)) { |
@@ -1142,7 +1144,9 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1142 | lastdirent = buf.previous; | 1144 | lastdirent = buf.previous; |
1143 | if (lastdirent) { | 1145 | if (lastdirent) { |
1144 | typeof(lastdirent->d_off) d_off = file->f_pos; | 1146 | typeof(lastdirent->d_off) d_off = file->f_pos; |
1145 | __put_user_unaligned(d_off, &lastdirent->d_off); | 1147 | error = -EFAULT; |
1148 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) | ||
1149 | goto out_putf; | ||
1146 | error = count - buf.count; | 1150 | error = count - buf.count; |
1147 | } | 1151 | } |
1148 | 1152 | ||
@@ -1255,7 +1259,7 @@ out: | |||
1255 | if (iov != iovstack) | 1259 | if (iov != iovstack) |
1256 | kfree(iov); | 1260 | kfree(iov); |
1257 | if ((ret + (type == READ)) > 0) { | 1261 | if ((ret + (type == READ)) > 0) { |
1258 | struct dentry *dentry = file->f_dentry; | 1262 | struct dentry *dentry = file->f_path.dentry; |
1259 | if (type == READ) | 1263 | if (type == READ) |
1260 | fsnotify_access(dentry); | 1264 | fsnotify_access(dentry); |
1261 | else | 1265 | else |
@@ -1609,14 +1613,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1609 | nr &= ~1UL; | 1613 | nr &= ~1UL; |
1610 | while (nr) { | 1614 | while (nr) { |
1611 | unsigned long h, l; | 1615 | unsigned long h, l; |
1612 | __get_user(l, ufdset); | 1616 | if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) |
1613 | __get_user(h, ufdset+1); | 1617 | return -EFAULT; |
1614 | ufdset += 2; | 1618 | ufdset += 2; |
1615 | *fdset++ = h << 32 | l; | 1619 | *fdset++ = h << 32 | l; |
1616 | nr -= 2; | 1620 | nr -= 2; |
1617 | } | 1621 | } |
1618 | if (odd) | 1622 | if (odd && __get_user(*fdset, ufdset)) |
1619 | __get_user(*fdset, ufdset); | 1623 | return -EFAULT; |
1620 | } else { | 1624 | } else { |
1621 | /* Tricky, must clear full unsigned long in the | 1625 | /* Tricky, must clear full unsigned long in the |
1622 | * kernel fdset at the end, this makes sure that | 1626 | * kernel fdset at the end, this makes sure that |
@@ -1628,14 +1632,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1628 | } | 1632 | } |
1629 | 1633 | ||
1630 | static | 1634 | static |
1631 | void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | 1635 | int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, |
1632 | unsigned long *fdset) | 1636 | unsigned long *fdset) |
1633 | { | 1637 | { |
1634 | unsigned long odd; | 1638 | unsigned long odd; |
1635 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); | 1639 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); |
1636 | 1640 | ||
1637 | if (!ufdset) | 1641 | if (!ufdset) |
1638 | return; | 1642 | return 0; |
1639 | 1643 | ||
1640 | odd = nr & 1UL; | 1644 | odd = nr & 1UL; |
1641 | nr &= ~1UL; | 1645 | nr &= ~1UL; |
@@ -1643,13 +1647,14 @@ void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1643 | unsigned long h, l; | 1647 | unsigned long h, l; |
1644 | l = *fdset++; | 1648 | l = *fdset++; |
1645 | h = l >> 32; | 1649 | h = l >> 32; |
1646 | __put_user(l, ufdset); | 1650 | if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) |
1647 | __put_user(h, ufdset+1); | 1651 | return -EFAULT; |
1648 | ufdset += 2; | 1652 | ufdset += 2; |
1649 | nr -= 2; | 1653 | nr -= 2; |
1650 | } | 1654 | } |
1651 | if (odd) | 1655 | if (odd && __put_user(*fdset, ufdset)) |
1652 | __put_user(*fdset, ufdset); | 1656 | return -EFAULT; |
1657 | return 0; | ||
1653 | } | 1658 | } |
1654 | 1659 | ||
1655 | 1660 | ||
@@ -1674,19 +1679,19 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1674 | { | 1679 | { |
1675 | fd_set_bits fds; | 1680 | fd_set_bits fds; |
1676 | char *bits; | 1681 | char *bits; |
1677 | int size, max_fdset, ret = -EINVAL; | 1682 | int size, max_fds, ret = -EINVAL; |
1678 | struct fdtable *fdt; | 1683 | struct fdtable *fdt; |
1679 | 1684 | ||
1680 | if (n < 0) | 1685 | if (n < 0) |
1681 | goto out_nofds; | 1686 | goto out_nofds; |
1682 | 1687 | ||
1683 | /* max_fdset can increase, so grab it once to avoid race */ | 1688 | /* max_fds can increase, so grab it once to avoid race */ |
1684 | rcu_read_lock(); | 1689 | rcu_read_lock(); |
1685 | fdt = files_fdtable(current->files); | 1690 | fdt = files_fdtable(current->files); |
1686 | max_fdset = fdt->max_fdset; | 1691 | max_fds = fdt->max_fds; |
1687 | rcu_read_unlock(); | 1692 | rcu_read_unlock(); |
1688 | if (n > max_fdset) | 1693 | if (n > max_fds) |
1689 | n = max_fdset; | 1694 | n = max_fds; |
1690 | 1695 | ||
1691 | /* | 1696 | /* |
1692 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), | 1697 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), |
@@ -1724,10 +1729,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1724 | ret = 0; | 1729 | ret = 0; |
1725 | } | 1730 | } |
1726 | 1731 | ||
1727 | compat_set_fd_set(n, inp, fds.res_in); | 1732 | if (compat_set_fd_set(n, inp, fds.res_in) || |
1728 | compat_set_fd_set(n, outp, fds.res_out); | 1733 | compat_set_fd_set(n, outp, fds.res_out) || |
1729 | compat_set_fd_set(n, exp, fds.res_ex); | 1734 | compat_set_fd_set(n, exp, fds.res_ex)) |
1730 | 1735 | ret = -EFAULT; | |
1731 | out: | 1736 | out: |
1732 | kfree(bits); | 1737 | kfree(bits); |
1733 | out_nofds: | 1738 | out_nofds: |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index a91f2628c981..c81c958b3e1d 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -211,8 +211,10 @@ static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned lon | |||
211 | up_native = | 211 | up_native = |
212 | compat_alloc_user_space(sizeof(struct video_still_picture)); | 212 | compat_alloc_user_space(sizeof(struct video_still_picture)); |
213 | 213 | ||
214 | put_user(compat_ptr(fp), &up_native->iFrame); | 214 | err = put_user(compat_ptr(fp), &up_native->iFrame); |
215 | put_user(size, &up_native->size); | 215 | err |= put_user(size, &up_native->size); |
216 | if (err) | ||
217 | return -EFAULT; | ||
216 | 218 | ||
217 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); | 219 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
218 | 220 | ||
@@ -236,8 +238,10 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned | |||
236 | err |= get_user(length, &up->length); | 238 | err |= get_user(length, &up->length); |
237 | 239 | ||
238 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); | 240 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); |
239 | put_user(compat_ptr(palp), &up_native->palette); | 241 | err = put_user(compat_ptr(palp), &up_native->palette); |
240 | put_user(length, &up_native->length); | 242 | err |= put_user(length, &up_native->length); |
243 | if (err) | ||
244 | return -EFAULT; | ||
241 | 245 | ||
242 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); | 246 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
243 | 247 | ||
@@ -1173,7 +1177,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar | |||
1173 | static int vt_check(struct file *file) | 1177 | static int vt_check(struct file *file) |
1174 | { | 1178 | { |
1175 | struct tty_struct *tty; | 1179 | struct tty_struct *tty; |
1176 | struct inode *inode = file->f_dentry->d_inode; | 1180 | struct inode *inode = file->f_path.dentry->d_inode; |
1177 | 1181 | ||
1178 | if (file->f_op->ioctl != tty_ioctl) | 1182 | if (file->f_op->ioctl != tty_ioctl) |
1179 | return -EINVAL; | 1183 | return -EINVAL; |
@@ -2043,16 +2047,19 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
2043 | struct serial_struct ss; | 2047 | struct serial_struct ss; |
2044 | mm_segment_t oldseg = get_fs(); | 2048 | mm_segment_t oldseg = get_fs(); |
2045 | __u32 udata; | 2049 | __u32 udata; |
2050 | unsigned int base; | ||
2046 | 2051 | ||
2047 | if (cmd == TIOCSSERIAL) { | 2052 | if (cmd == TIOCSSERIAL) { |
2048 | if (!access_ok(VERIFY_READ, ss32, sizeof(SS32))) | 2053 | if (!access_ok(VERIFY_READ, ss32, sizeof(SS32))) |
2049 | return -EFAULT; | 2054 | return -EFAULT; |
2050 | if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base))) | 2055 | if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base))) |
2051 | return -EFAULT; | 2056 | return -EFAULT; |
2052 | __get_user(udata, &ss32->iomem_base); | 2057 | if (__get_user(udata, &ss32->iomem_base)) |
2058 | return -EFAULT; | ||
2053 | ss.iomem_base = compat_ptr(udata); | 2059 | ss.iomem_base = compat_ptr(udata); |
2054 | __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); | 2060 | if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || |
2055 | __get_user(ss.port_high, &ss32->port_high); | 2061 | __get_user(ss.port_high, &ss32->port_high)) |
2062 | return -EFAULT; | ||
2056 | ss.iomap_base = 0UL; | 2063 | ss.iomap_base = 0UL; |
2057 | } | 2064 | } |
2058 | set_fs(KERNEL_DS); | 2065 | set_fs(KERNEL_DS); |
@@ -2063,12 +2070,12 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
2063 | return -EFAULT; | 2070 | return -EFAULT; |
2064 | if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base))) | 2071 | if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base))) |
2065 | return -EFAULT; | 2072 | return -EFAULT; |
2066 | __put_user((unsigned long)ss.iomem_base >> 32 ? | 2073 | base = (unsigned long)ss.iomem_base >> 32 ? |
2067 | 0xffffffff : (unsigned)(unsigned long)ss.iomem_base, | 2074 | 0xffffffff : (unsigned)(unsigned long)ss.iomem_base; |
2068 | &ss32->iomem_base); | 2075 | if (__put_user(base, &ss32->iomem_base) || |
2069 | __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); | 2076 | __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || |
2070 | __put_user(ss.port_high, &ss32->port_high); | 2077 | __put_user(ss.port_high, &ss32->port_high)) |
2071 | 2078 | return -EFAULT; | |
2072 | } | 2079 | } |
2073 | return err; | 2080 | return err; |
2074 | } | 2081 | } |
@@ -2397,6 +2404,7 @@ HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) | |||
2397 | HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) | 2404 | HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) |
2398 | HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) | 2405 | HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) |
2399 | HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) | 2406 | HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) |
2407 | HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc) | ||
2400 | 2408 | ||
2401 | /* ioctls used by appletalk ddp.c */ | 2409 | /* ioctls used by appletalk ddp.c */ |
2402 | HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) | 2410 | HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) |
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 3f4ff7a242b9..f92cd303d2c9 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
@@ -49,7 +49,7 @@ struct configfs_dirent { | |||
49 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) | 49 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) |
50 | 50 | ||
51 | extern struct vfsmount * configfs_mount; | 51 | extern struct vfsmount * configfs_mount; |
52 | extern kmem_cache_t *configfs_dir_cachep; | 52 | extern struct kmem_cache *configfs_dir_cachep; |
53 | 53 | ||
54 | extern int configfs_is_root(struct config_item *item); | 54 | extern int configfs_is_root(struct config_item *item); |
55 | 55 | ||
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 8a3b6a1a6ad1..1814ba446809 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -93,8 +93,8 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare | |||
93 | * | 93 | * |
94 | * called with parent inode's i_mutex held | 94 | * called with parent inode's i_mutex held |
95 | */ | 95 | */ |
96 | int configfs_dirent_exists(struct configfs_dirent *parent_sd, | 96 | static int configfs_dirent_exists(struct configfs_dirent *parent_sd, |
97 | const unsigned char *new) | 97 | const unsigned char *new) |
98 | { | 98 | { |
99 | struct configfs_dirent * sd; | 99 | struct configfs_dirent * sd; |
100 | 100 | ||
@@ -980,7 +980,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name) | |||
980 | 980 | ||
981 | static int configfs_dir_open(struct inode *inode, struct file *file) | 981 | static int configfs_dir_open(struct inode *inode, struct file *file) |
982 | { | 982 | { |
983 | struct dentry * dentry = file->f_dentry; | 983 | struct dentry * dentry = file->f_path.dentry; |
984 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 984 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
985 | 985 | ||
986 | mutex_lock(&dentry->d_inode->i_mutex); | 986 | mutex_lock(&dentry->d_inode->i_mutex); |
@@ -993,7 +993,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file) | |||
993 | 993 | ||
994 | static int configfs_dir_close(struct inode *inode, struct file *file) | 994 | static int configfs_dir_close(struct inode *inode, struct file *file) |
995 | { | 995 | { |
996 | struct dentry * dentry = file->f_dentry; | 996 | struct dentry * dentry = file->f_path.dentry; |
997 | struct configfs_dirent * cursor = file->private_data; | 997 | struct configfs_dirent * cursor = file->private_data; |
998 | 998 | ||
999 | mutex_lock(&dentry->d_inode->i_mutex); | 999 | mutex_lock(&dentry->d_inode->i_mutex); |
@@ -1013,7 +1013,7 @@ static inline unsigned char dt_type(struct configfs_dirent *sd) | |||
1013 | 1013 | ||
1014 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 1014 | static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
1015 | { | 1015 | { |
1016 | struct dentry *dentry = filp->f_dentry; | 1016 | struct dentry *dentry = filp->f_path.dentry; |
1017 | struct configfs_dirent * parent_sd = dentry->d_fsdata; | 1017 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
1018 | struct configfs_dirent *cursor = filp->private_data; | 1018 | struct configfs_dirent *cursor = filp->private_data; |
1019 | struct list_head *p, *q = &cursor->s_sibling; | 1019 | struct list_head *p, *q = &cursor->s_sibling; |
@@ -1070,7 +1070,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir | |||
1070 | 1070 | ||
1071 | static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) | 1071 | static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) |
1072 | { | 1072 | { |
1073 | struct dentry * dentry = file->f_dentry; | 1073 | struct dentry * dentry = file->f_path.dentry; |
1074 | 1074 | ||
1075 | mutex_lock(&dentry->d_inode->i_mutex); | 1075 | mutex_lock(&dentry->d_inode->i_mutex); |
1076 | switch (origin) { | 1076 | switch (origin) { |
@@ -1080,7 +1080,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
1080 | if (offset >= 0) | 1080 | if (offset >= 0) |
1081 | break; | 1081 | break; |
1082 | default: | 1082 | default: |
1083 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 1083 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
1084 | return -EINVAL; | 1084 | return -EINVAL; |
1085 | } | 1085 | } |
1086 | if (offset != file->f_pos) { | 1086 | if (offset != file->f_pos) { |
@@ -1176,8 +1176,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1176 | return; | 1176 | return; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); | 1179 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, |
1180 | mutex_lock(&dentry->d_inode->i_mutex); | 1180 | I_MUTEX_PARENT); |
1181 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | ||
1181 | if (configfs_detach_prep(dentry)) { | 1182 | if (configfs_detach_prep(dentry)) { |
1182 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); | 1183 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); |
1183 | } | 1184 | } |
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index cf33fac68c84..2a7cb086e80c 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
@@ -134,7 +134,7 @@ configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *pp | |||
134 | 134 | ||
135 | down(&buffer->sem); | 135 | down(&buffer->sem); |
136 | if (buffer->needs_read_fill) { | 136 | if (buffer->needs_read_fill) { |
137 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) | 137 | if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) |
138 | goto out; | 138 | goto out; |
139 | } | 139 | } |
140 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", | 140 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
@@ -222,7 +222,7 @@ configfs_write_file(struct file *file, const char __user *buf, size_t count, lof | |||
222 | down(&buffer->sem); | 222 | down(&buffer->sem); |
223 | len = fill_write_buffer(buffer, buf, count); | 223 | len = fill_write_buffer(buffer, buf, count); |
224 | if (len > 0) | 224 | if (len > 0) |
225 | len = flush_write_buffer(file->f_dentry, buffer, count); | 225 | len = flush_write_buffer(file->f_path.dentry, buffer, count); |
226 | if (len > 0) | 226 | if (len > 0) |
227 | *ppos += len; | 227 | *ppos += len; |
228 | up(&buffer->sem); | 228 | up(&buffer->sem); |
@@ -231,8 +231,8 @@ configfs_write_file(struct file *file, const char __user *buf, size_t count, lof | |||
231 | 231 | ||
232 | static int check_perm(struct inode * inode, struct file * file) | 232 | static int check_perm(struct inode * inode, struct file * file) |
233 | { | 233 | { |
234 | struct config_item *item = configfs_get_config_item(file->f_dentry->d_parent); | 234 | struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent); |
235 | struct configfs_attribute * attr = to_attr(file->f_dentry); | 235 | struct configfs_attribute * attr = to_attr(file->f_path.dentry); |
236 | struct configfs_buffer * buffer; | 236 | struct configfs_buffer * buffer; |
237 | struct configfs_item_operations * ops = NULL; | 237 | struct configfs_item_operations * ops = NULL; |
238 | int error = 0; | 238 | int error = 0; |
@@ -305,8 +305,8 @@ static int configfs_open_file(struct inode * inode, struct file * filp) | |||
305 | 305 | ||
306 | static int configfs_release(struct inode * inode, struct file * filp) | 306 | static int configfs_release(struct inode * inode, struct file * filp) |
307 | { | 307 | { |
308 | struct config_item * item = to_item(filp->f_dentry->d_parent); | 308 | struct config_item * item = to_item(filp->f_path.dentry->d_parent); |
309 | struct configfs_attribute * attr = to_attr(filp->f_dentry); | 309 | struct configfs_attribute * attr = to_attr(filp->f_path.dentry); |
310 | struct module * owner = attr->ca_owner; | 310 | struct module * owner = attr->ca_owner; |
311 | struct configfs_buffer * buffer = filp->private_data; | 311 | struct configfs_buffer * buffer = filp->private_data; |
312 | 312 | ||
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 68bd5c93ca52..ed678529ebb2 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | struct vfsmount * configfs_mount = NULL; | 39 | struct vfsmount * configfs_mount = NULL; |
40 | struct super_block * configfs_sb = NULL; | 40 | struct super_block * configfs_sb = NULL; |
41 | kmem_cache_t *configfs_dir_cachep; | 41 | struct kmem_cache *configfs_dir_cachep; |
42 | static int configfs_mnt_count = 0; | 42 | static int configfs_mnt_count = 0; |
43 | 43 | ||
44 | static struct super_operations configfs_ops = { | 44 | static struct super_operations configfs_ops = { |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a624c3ec8189..6db03fb089dc 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -338,7 +338,7 @@ static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
338 | */ | 338 | */ |
339 | static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 339 | static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
340 | { | 340 | { |
341 | struct inode *inode = filp->f_dentry->d_inode; | 341 | struct inode *inode = filp->f_path.dentry->d_inode; |
342 | struct super_block *sb = inode->i_sb; | 342 | struct super_block *sb = inode->i_sb; |
343 | char *buf; | 343 | char *buf; |
344 | unsigned int offset; | 344 | unsigned int offset; |
@@ -481,6 +481,8 @@ static int cramfs_readpage(struct file *file, struct page * page) | |||
481 | pgdata = kmap(page); | 481 | pgdata = kmap(page); |
482 | if (compr_len == 0) | 482 | if (compr_len == 0) |
483 | ; /* hole */ | 483 | ; /* hole */ |
484 | else if (compr_len > (PAGE_CACHE_SIZE << 1)) | ||
485 | printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); | ||
484 | else { | 486 | else { |
485 | mutex_lock(&read_mutex); | 487 | mutex_lock(&read_mutex); |
486 | bytes_filled = cramfs_uncompress_block(pgdata, | 488 | bytes_filled = cramfs_uncompress_block(pgdata, |
diff --git a/fs/dcache.c b/fs/dcache.c index fd4a428998ef..d68631f18df1 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -43,7 +43,7 @@ static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); | |||
43 | 43 | ||
44 | EXPORT_SYMBOL(dcache_lock); | 44 | EXPORT_SYMBOL(dcache_lock); |
45 | 45 | ||
46 | static kmem_cache_t *dentry_cache __read_mostly; | 46 | static struct kmem_cache *dentry_cache __read_mostly; |
47 | 47 | ||
48 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) | 48 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) |
49 | 49 | ||
@@ -68,15 +68,19 @@ struct dentry_stat_t dentry_stat = { | |||
68 | .age_limit = 45, | 68 | .age_limit = 45, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static void d_callback(struct rcu_head *head) | 71 | static void __d_free(struct dentry *dentry) |
72 | { | 72 | { |
73 | struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
74 | |||
75 | if (dname_external(dentry)) | 73 | if (dname_external(dentry)) |
76 | kfree(dentry->d_name.name); | 74 | kfree(dentry->d_name.name); |
77 | kmem_cache_free(dentry_cache, dentry); | 75 | kmem_cache_free(dentry_cache, dentry); |
78 | } | 76 | } |
79 | 77 | ||
78 | static void d_callback(struct rcu_head *head) | ||
79 | { | ||
80 | struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
81 | __d_free(dentry); | ||
82 | } | ||
83 | |||
80 | /* | 84 | /* |
81 | * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry | 85 | * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry |
82 | * inside dcache_lock. | 86 | * inside dcache_lock. |
@@ -85,7 +89,11 @@ static void d_free(struct dentry *dentry) | |||
85 | { | 89 | { |
86 | if (dentry->d_op && dentry->d_op->d_release) | 90 | if (dentry->d_op && dentry->d_op->d_release) |
87 | dentry->d_op->d_release(dentry); | 91 | dentry->d_op->d_release(dentry); |
88 | call_rcu(&dentry->d_u.d_rcu, d_callback); | 92 | /* if dentry was never inserted into hash, immediate free is OK */ |
93 | if (dentry->d_hash.pprev == NULL) | ||
94 | __d_free(dentry); | ||
95 | else | ||
96 | call_rcu(&dentry->d_u.d_rcu, d_callback); | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /* | 99 | /* |
@@ -2072,10 +2080,10 @@ static void __init dcache_init(unsigned long mempages) | |||
2072 | } | 2080 | } |
2073 | 2081 | ||
2074 | /* SLAB cache for __getname() consumers */ | 2082 | /* SLAB cache for __getname() consumers */ |
2075 | kmem_cache_t *names_cachep __read_mostly; | 2083 | struct kmem_cache *names_cachep __read_mostly; |
2076 | 2084 | ||
2077 | /* SLAB cache for file structures */ | 2085 | /* SLAB cache for file structures */ |
2078 | kmem_cache_t *filp_cachep __read_mostly; | 2086 | struct kmem_cache *filp_cachep __read_mostly; |
2079 | 2087 | ||
2080 | EXPORT_SYMBOL(d_genocide); | 2088 | EXPORT_SYMBOL(d_genocide); |
2081 | 2089 | ||
diff --git a/fs/dcookies.c b/fs/dcookies.c index 0c4b0674854b..21af1629f9bc 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c | |||
@@ -37,7 +37,7 @@ struct dcookie_struct { | |||
37 | 37 | ||
38 | static LIST_HEAD(dcookie_users); | 38 | static LIST_HEAD(dcookie_users); |
39 | static DEFINE_MUTEX(dcookie_mutex); | 39 | static DEFINE_MUTEX(dcookie_mutex); |
40 | static kmem_cache_t *dcookie_cache __read_mostly; | 40 | static struct kmem_cache *dcookie_cache __read_mostly; |
41 | static struct list_head *dcookie_hashtable __read_mostly; | 41 | static struct list_head *dcookie_hashtable __read_mostly; |
42 | static size_t hash_size __read_mostly; | 42 | static size_t hash_size __read_mostly; |
43 | 43 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 137d76c3f90a..c692487346ea 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kobject.h> | 24 | #include <linux/kobject.h> |
25 | #include <linux/namei.h> | 25 | #include <linux/namei.h> |
26 | #include <linux/debugfs.h> | 26 | #include <linux/debugfs.h> |
27 | #include <linux/fsnotify.h> | ||
27 | 28 | ||
28 | #define DEBUGFS_MAGIC 0x64626720 | 29 | #define DEBUGFS_MAGIC 0x64626720 |
29 | 30 | ||
@@ -54,7 +55,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d | |||
54 | inode->i_op = &simple_dir_inode_operations; | 55 | inode->i_op = &simple_dir_inode_operations; |
55 | inode->i_fop = &simple_dir_operations; | 56 | inode->i_fop = &simple_dir_operations; |
56 | 57 | ||
57 | /* directory inodes start off with i_nlink == 2 (for "." entry) */ | 58 | /* directory inodes start off with i_nlink == 2 |
59 | * (for "." entry) */ | ||
58 | inc_nlink(inode); | 60 | inc_nlink(inode); |
59 | break; | 61 | break; |
60 | } | 62 | } |
@@ -87,15 +89,22 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
87 | 89 | ||
88 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; | 90 | mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; |
89 | res = debugfs_mknod(dir, dentry, mode, 0); | 91 | res = debugfs_mknod(dir, dentry, mode, 0); |
90 | if (!res) | 92 | if (!res) { |
91 | inc_nlink(dir); | 93 | inc_nlink(dir); |
94 | fsnotify_mkdir(dir, dentry); | ||
95 | } | ||
92 | return res; | 96 | return res; |
93 | } | 97 | } |
94 | 98 | ||
95 | static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) | 99 | static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) |
96 | { | 100 | { |
101 | int res; | ||
102 | |||
97 | mode = (mode & S_IALLUGO) | S_IFREG; | 103 | mode = (mode & S_IALLUGO) | S_IFREG; |
98 | return debugfs_mknod(dir, dentry, mode, 0); | 104 | res = debugfs_mknod(dir, dentry, mode, 0); |
105 | if (!res) | ||
106 | fsnotify_create(dir, dentry); | ||
107 | return res; | ||
99 | } | 108 | } |
100 | 109 | ||
101 | static inline int debugfs_positive(struct dentry *dentry) | 110 | static inline int debugfs_positive(struct dentry *dentry) |
@@ -135,7 +144,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
135 | * block. A pointer to that is in the struct vfsmount that we | 144 | * block. A pointer to that is in the struct vfsmount that we |
136 | * have around. | 145 | * have around. |
137 | */ | 146 | */ |
138 | if (!parent ) { | 147 | if (!parent) { |
139 | if (debugfs_mount && debugfs_mount->mnt_sb) { | 148 | if (debugfs_mount && debugfs_mount->mnt_sb) { |
140 | parent = debugfs_mount->mnt_sb->s_root; | 149 | parent = debugfs_mount->mnt_sb->s_root; |
141 | } | 150 | } |
@@ -153,6 +162,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
153 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); | 162 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); |
154 | else | 163 | else |
155 | error = debugfs_create(parent->d_inode, *dentry, mode); | 164 | error = debugfs_create(parent->d_inode, *dentry, mode); |
165 | dput(*dentry); | ||
156 | } else | 166 | } else |
157 | error = PTR_ERR(*dentry); | 167 | error = PTR_ERR(*dentry); |
158 | mutex_unlock(&parent->d_inode->i_mutex); | 168 | mutex_unlock(&parent->d_inode->i_mutex); |
@@ -197,13 +207,15 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode, | |||
197 | 207 | ||
198 | pr_debug("debugfs: creating file '%s'\n",name); | 208 | pr_debug("debugfs: creating file '%s'\n",name); |
199 | 209 | ||
200 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count); | 210 | error = simple_pin_fs(&debug_fs_type, &debugfs_mount, |
211 | &debugfs_mount_count); | ||
201 | if (error) | 212 | if (error) |
202 | goto exit; | 213 | goto exit; |
203 | 214 | ||
204 | error = debugfs_create_by_name(name, mode, parent, &dentry); | 215 | error = debugfs_create_by_name(name, mode, parent, &dentry); |
205 | if (error) { | 216 | if (error) { |
206 | dentry = NULL; | 217 | dentry = NULL; |
218 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
207 | goto exit; | 219 | goto exit; |
208 | } | 220 | } |
209 | 221 | ||
@@ -262,6 +274,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir); | |||
262 | void debugfs_remove(struct dentry *dentry) | 274 | void debugfs_remove(struct dentry *dentry) |
263 | { | 275 | { |
264 | struct dentry *parent; | 276 | struct dentry *parent; |
277 | int ret = 0; | ||
265 | 278 | ||
266 | if (!dentry) | 279 | if (!dentry) |
267 | return; | 280 | return; |
@@ -273,11 +286,19 @@ void debugfs_remove(struct dentry *dentry) | |||
273 | mutex_lock(&parent->d_inode->i_mutex); | 286 | mutex_lock(&parent->d_inode->i_mutex); |
274 | if (debugfs_positive(dentry)) { | 287 | if (debugfs_positive(dentry)) { |
275 | if (dentry->d_inode) { | 288 | if (dentry->d_inode) { |
276 | if (S_ISDIR(dentry->d_inode->i_mode)) | 289 | dget(dentry); |
277 | simple_rmdir(parent->d_inode, dentry); | 290 | if (S_ISDIR(dentry->d_inode->i_mode)) { |
278 | else | 291 | ret = simple_rmdir(parent->d_inode, dentry); |
292 | if (ret) | ||
293 | printk(KERN_ERR | ||
294 | "DebugFS rmdir on %s failed : " | ||
295 | "directory not empty.\n", | ||
296 | dentry->d_name.name); | ||
297 | } else | ||
279 | simple_unlink(parent->d_inode, dentry); | 298 | simple_unlink(parent->d_inode, dentry); |
280 | dput(dentry); | 299 | if (!ret) |
300 | d_delete(dentry); | ||
301 | dput(dentry); | ||
281 | } | 302 | } |
282 | } | 303 | } |
283 | mutex_unlock(&parent->d_inode->i_mutex); | 304 | mutex_unlock(&parent->d_inode->i_mutex); |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 5981e17f46f0..d9d0833444f5 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/task_io_accounting_ops.h> | ||
30 | #include <linux/bio.h> | 31 | #include <linux/bio.h> |
31 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
32 | #include <linux/err.h> | 33 | #include <linux/err.h> |
@@ -121,8 +122,7 @@ struct dio { | |||
121 | 122 | ||
122 | /* BIO completion state */ | 123 | /* BIO completion state */ |
123 | spinlock_t bio_lock; /* protects BIO fields below */ | 124 | spinlock_t bio_lock; /* protects BIO fields below */ |
124 | int bio_count; /* nr bios to be completed */ | 125 | unsigned long refcount; /* direct_io_worker() and bios */ |
125 | int bios_in_flight; /* nr bios in flight */ | ||
126 | struct bio *bio_list; /* singly linked via bi_private */ | 126 | struct bio *bio_list; /* singly linked via bi_private */ |
127 | struct task_struct *waiter; /* waiting task (NULL if none) */ | 127 | struct task_struct *waiter; /* waiting task (NULL if none) */ |
128 | 128 | ||
@@ -209,76 +209,55 @@ static struct page *dio_get_page(struct dio *dio) | |||
209 | return dio->pages[dio->head++]; | 209 | return dio->pages[dio->head++]; |
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /** |
213 | * Called when all DIO BIO I/O has been completed - let the filesystem | 213 | * dio_complete() - called when all DIO BIO I/O has been completed |
214 | * know, if it registered an interest earlier via get_block. Pass the | 214 | * @offset: the byte offset in the file of the completed operation |
215 | * private field of the map buffer_head so that filesystems can use it | 215 | * |
216 | * to hold additional state between get_block calls and dio_complete. | 216 | * This releases locks as dictated by the locking type, lets interested parties |
217 | */ | 217 | * know that a DIO operation has completed, and calculates the resulting return |
218 | static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes) | 218 | * code for the operation. |
219 | { | 219 | * |
220 | if (dio->end_io && dio->result) | 220 | * It lets the filesystem know if it registered an interest earlier via |
221 | dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private); | 221 | * get_block. Pass the private field of the map buffer_head so that |
222 | if (dio->lock_type == DIO_LOCKING) | 222 | * filesystems can use it to hold additional state between get_block calls and |
223 | /* lockdep: non-owner release */ | 223 | * dio_complete. |
224 | up_read_non_owner(&dio->inode->i_alloc_sem); | ||
225 | } | ||
226 | |||
227 | /* | ||
228 | * Called when a BIO has been processed. If the count goes to zero then IO is | ||
229 | * complete and we can signal this to the AIO layer. | ||
230 | */ | 224 | */ |
231 | static void finished_one_bio(struct dio *dio) | 225 | static int dio_complete(struct dio *dio, loff_t offset, int ret) |
232 | { | 226 | { |
233 | unsigned long flags; | 227 | ssize_t transferred = 0; |
234 | 228 | ||
235 | spin_lock_irqsave(&dio->bio_lock, flags); | 229 | /* |
236 | if (dio->bio_count == 1) { | 230 | * AIO submission can race with bio completion to get here while |
237 | if (dio->is_async) { | 231 | * expecting to have the last io completed by bio completion. |
238 | ssize_t transferred; | 232 | * In that case -EIOCBQUEUED is in fact not an error we want |
239 | loff_t offset; | 233 | * to preserve through this call. |
240 | 234 | */ | |
241 | /* | 235 | if (ret == -EIOCBQUEUED) |
242 | * Last reference to the dio is going away. | 236 | ret = 0; |
243 | * Drop spinlock and complete the DIO. | ||
244 | */ | ||
245 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
246 | 237 | ||
247 | /* Check for short read case */ | 238 | if (dio->result) { |
248 | transferred = dio->result; | 239 | transferred = dio->result; |
249 | offset = dio->iocb->ki_pos; | ||
250 | 240 | ||
251 | if ((dio->rw == READ) && | 241 | /* Check for short read case */ |
252 | ((offset + transferred) > dio->i_size)) | 242 | if ((dio->rw == READ) && ((offset + transferred) > dio->i_size)) |
253 | transferred = dio->i_size - offset; | 243 | transferred = dio->i_size - offset; |
244 | } | ||
254 | 245 | ||
255 | /* check for error in completion path */ | 246 | if (dio->end_io && dio->result) |
256 | if (dio->io_error) | 247 | dio->end_io(dio->iocb, offset, transferred, |
257 | transferred = dio->io_error; | 248 | dio->map_bh.b_private); |
249 | if (dio->lock_type == DIO_LOCKING) | ||
250 | /* lockdep: non-owner release */ | ||
251 | up_read_non_owner(&dio->inode->i_alloc_sem); | ||
258 | 252 | ||
259 | dio_complete(dio, offset, transferred); | 253 | if (ret == 0) |
254 | ret = dio->page_errors; | ||
255 | if (ret == 0) | ||
256 | ret = dio->io_error; | ||
257 | if (ret == 0) | ||
258 | ret = transferred; | ||
260 | 259 | ||
261 | /* Complete AIO later if falling back to buffered i/o */ | 260 | return ret; |
262 | if (dio->result == dio->size || | ||
263 | ((dio->rw == READ) && dio->result)) { | ||
264 | aio_complete(dio->iocb, transferred, 0); | ||
265 | kfree(dio); | ||
266 | return; | ||
267 | } else { | ||
268 | /* | ||
269 | * Falling back to buffered | ||
270 | */ | ||
271 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
272 | dio->bio_count--; | ||
273 | if (dio->waiter) | ||
274 | wake_up_process(dio->waiter); | ||
275 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
276 | return; | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | dio->bio_count--; | ||
281 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
282 | } | 261 | } |
283 | 262 | ||
284 | static int dio_bio_complete(struct dio *dio, struct bio *bio); | 263 | static int dio_bio_complete(struct dio *dio, struct bio *bio); |
@@ -288,12 +267,27 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio); | |||
288 | static int dio_bio_end_aio(struct bio *bio, unsigned int bytes_done, int error) | 267 | static int dio_bio_end_aio(struct bio *bio, unsigned int bytes_done, int error) |
289 | { | 268 | { |
290 | struct dio *dio = bio->bi_private; | 269 | struct dio *dio = bio->bi_private; |
270 | unsigned long remaining; | ||
271 | unsigned long flags; | ||
291 | 272 | ||
292 | if (bio->bi_size) | 273 | if (bio->bi_size) |
293 | return 1; | 274 | return 1; |
294 | 275 | ||
295 | /* cleanup the bio */ | 276 | /* cleanup the bio */ |
296 | dio_bio_complete(dio, bio); | 277 | dio_bio_complete(dio, bio); |
278 | |||
279 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
280 | remaining = --dio->refcount; | ||
281 | if (remaining == 1 && dio->waiter) | ||
282 | wake_up_process(dio->waiter); | ||
283 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
284 | |||
285 | if (remaining == 0) { | ||
286 | int ret = dio_complete(dio, dio->iocb->ki_pos, 0); | ||
287 | aio_complete(dio->iocb, ret, 0); | ||
288 | kfree(dio); | ||
289 | } | ||
290 | |||
297 | return 0; | 291 | return 0; |
298 | } | 292 | } |
299 | 293 | ||
@@ -315,8 +309,7 @@ static int dio_bio_end_io(struct bio *bio, unsigned int bytes_done, int error) | |||
315 | spin_lock_irqsave(&dio->bio_lock, flags); | 309 | spin_lock_irqsave(&dio->bio_lock, flags); |
316 | bio->bi_private = dio->bio_list; | 310 | bio->bi_private = dio->bio_list; |
317 | dio->bio_list = bio; | 311 | dio->bio_list = bio; |
318 | dio->bios_in_flight--; | 312 | if (--dio->refcount == 1 && dio->waiter) |
319 | if (dio->waiter && dio->bios_in_flight == 0) | ||
320 | wake_up_process(dio->waiter); | 313 | wake_up_process(dio->waiter); |
321 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 314 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
322 | return 0; | 315 | return 0; |
@@ -347,6 +340,8 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev, | |||
347 | * In the AIO read case we speculatively dirty the pages before starting IO. | 340 | * In the AIO read case we speculatively dirty the pages before starting IO. |
348 | * During IO completion, any of these pages which happen to have been written | 341 | * During IO completion, any of these pages which happen to have been written |
349 | * back will be redirtied by bio_check_pages_dirty(). | 342 | * back will be redirtied by bio_check_pages_dirty(). |
343 | * | ||
344 | * bios hold a dio reference between submit_bio and ->end_io. | ||
350 | */ | 345 | */ |
351 | static void dio_bio_submit(struct dio *dio) | 346 | static void dio_bio_submit(struct dio *dio) |
352 | { | 347 | { |
@@ -354,12 +349,14 @@ static void dio_bio_submit(struct dio *dio) | |||
354 | unsigned long flags; | 349 | unsigned long flags; |
355 | 350 | ||
356 | bio->bi_private = dio; | 351 | bio->bi_private = dio; |
352 | |||
357 | spin_lock_irqsave(&dio->bio_lock, flags); | 353 | spin_lock_irqsave(&dio->bio_lock, flags); |
358 | dio->bio_count++; | 354 | dio->refcount++; |
359 | dio->bios_in_flight++; | ||
360 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 355 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
356 | |||
361 | if (dio->is_async && dio->rw == READ) | 357 | if (dio->is_async && dio->rw == READ) |
362 | bio_set_pages_dirty(bio); | 358 | bio_set_pages_dirty(bio); |
359 | |||
363 | submit_bio(dio->rw, bio); | 360 | submit_bio(dio->rw, bio); |
364 | 361 | ||
365 | dio->bio = NULL; | 362 | dio->bio = NULL; |
@@ -376,28 +373,37 @@ static void dio_cleanup(struct dio *dio) | |||
376 | } | 373 | } |
377 | 374 | ||
378 | /* | 375 | /* |
379 | * Wait for the next BIO to complete. Remove it and return it. | 376 | * Wait for the next BIO to complete. Remove it and return it. NULL is |
377 | * returned once all BIOs have been completed. This must only be called once | ||
378 | * all bios have been issued so that dio->refcount can only decrease. This | ||
379 | * requires that that the caller hold a reference on the dio. | ||
380 | */ | 380 | */ |
381 | static struct bio *dio_await_one(struct dio *dio) | 381 | static struct bio *dio_await_one(struct dio *dio) |
382 | { | 382 | { |
383 | unsigned long flags; | 383 | unsigned long flags; |
384 | struct bio *bio; | 384 | struct bio *bio = NULL; |
385 | 385 | ||
386 | spin_lock_irqsave(&dio->bio_lock, flags); | 386 | spin_lock_irqsave(&dio->bio_lock, flags); |
387 | while (dio->bio_list == NULL) { | 387 | |
388 | set_current_state(TASK_UNINTERRUPTIBLE); | 388 | /* |
389 | if (dio->bio_list == NULL) { | 389 | * Wait as long as the list is empty and there are bios in flight. bio |
390 | dio->waiter = current; | 390 | * completion drops the count, maybe adds to the list, and wakes while |
391 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 391 | * holding the bio_lock so we don't need set_current_state()'s barrier |
392 | blk_run_address_space(dio->inode->i_mapping); | 392 | * and can call it after testing our condition. |
393 | io_schedule(); | 393 | */ |
394 | spin_lock_irqsave(&dio->bio_lock, flags); | 394 | while (dio->refcount > 1 && dio->bio_list == NULL) { |
395 | dio->waiter = NULL; | 395 | __set_current_state(TASK_UNINTERRUPTIBLE); |
396 | } | 396 | dio->waiter = current; |
397 | set_current_state(TASK_RUNNING); | 397 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
398 | io_schedule(); | ||
399 | /* wake up sets us TASK_RUNNING */ | ||
400 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
401 | dio->waiter = NULL; | ||
402 | } | ||
403 | if (dio->bio_list) { | ||
404 | bio = dio->bio_list; | ||
405 | dio->bio_list = bio->bi_private; | ||
398 | } | 406 | } |
399 | bio = dio->bio_list; | ||
400 | dio->bio_list = bio->bi_private; | ||
401 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 407 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
402 | return bio; | 408 | return bio; |
403 | } | 409 | } |
@@ -426,34 +432,24 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) | |||
426 | } | 432 | } |
427 | bio_put(bio); | 433 | bio_put(bio); |
428 | } | 434 | } |
429 | finished_one_bio(dio); | ||
430 | return uptodate ? 0 : -EIO; | 435 | return uptodate ? 0 : -EIO; |
431 | } | 436 | } |
432 | 437 | ||
433 | /* | 438 | /* |
434 | * Wait on and process all in-flight BIOs. | 439 | * Wait on and process all in-flight BIOs. This must only be called once |
440 | * all bios have been issued so that the refcount can only decrease. | ||
441 | * This just waits for all bios to make it through dio_bio_complete. IO | ||
442 | * errors are propogated through dio->io_error and should be propogated via | ||
443 | * dio_complete(). | ||
435 | */ | 444 | */ |
436 | static int dio_await_completion(struct dio *dio) | 445 | static void dio_await_completion(struct dio *dio) |
437 | { | 446 | { |
438 | int ret = 0; | 447 | struct bio *bio; |
439 | 448 | do { | |
440 | if (dio->bio) | 449 | bio = dio_await_one(dio); |
441 | dio_bio_submit(dio); | 450 | if (bio) |
442 | 451 | dio_bio_complete(dio, bio); | |
443 | /* | 452 | } while (bio); |
444 | * The bio_lock is not held for the read of bio_count. | ||
445 | * This is ok since it is the dio_bio_complete() that changes | ||
446 | * bio_count. | ||
447 | */ | ||
448 | while (dio->bio_count) { | ||
449 | struct bio *bio = dio_await_one(dio); | ||
450 | int ret2; | ||
451 | |||
452 | ret2 = dio_bio_complete(dio, bio); | ||
453 | if (ret == 0) | ||
454 | ret = ret2; | ||
455 | } | ||
456 | return ret; | ||
457 | } | 453 | } |
458 | 454 | ||
459 | /* | 455 | /* |
@@ -675,6 +671,13 @@ submit_page_section(struct dio *dio, struct page *page, | |||
675 | { | 671 | { |
676 | int ret = 0; | 672 | int ret = 0; |
677 | 673 | ||
674 | if (dio->rw & WRITE) { | ||
675 | /* | ||
676 | * Read accounting is performed in submit_bio() | ||
677 | */ | ||
678 | task_io_account_write(len); | ||
679 | } | ||
680 | |||
678 | /* | 681 | /* |
679 | * Can we just grow the current page's presence in the dio? | 682 | * Can we just grow the current page's presence in the dio? |
680 | */ | 683 | */ |
@@ -953,6 +956,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
953 | struct dio *dio) | 956 | struct dio *dio) |
954 | { | 957 | { |
955 | unsigned long user_addr; | 958 | unsigned long user_addr; |
959 | unsigned long flags; | ||
956 | int seg; | 960 | int seg; |
957 | ssize_t ret = 0; | 961 | ssize_t ret = 0; |
958 | ssize_t ret2; | 962 | ssize_t ret2; |
@@ -983,17 +987,8 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
983 | dio->iocb = iocb; | 987 | dio->iocb = iocb; |
984 | dio->i_size = i_size_read(inode); | 988 | dio->i_size = i_size_read(inode); |
985 | 989 | ||
986 | /* | ||
987 | * BIO completion state. | ||
988 | * | ||
989 | * ->bio_count starts out at one, and we decrement it to zero after all | ||
990 | * BIOs are submitted. This to avoid the situation where a really fast | ||
991 | * (or synchronous) device could take the count to zero while we're | ||
992 | * still submitting BIOs. | ||
993 | */ | ||
994 | dio->bio_count = 1; | ||
995 | dio->bios_in_flight = 0; | ||
996 | spin_lock_init(&dio->bio_lock); | 990 | spin_lock_init(&dio->bio_lock); |
991 | dio->refcount = 1; | ||
997 | dio->bio_list = NULL; | 992 | dio->bio_list = NULL; |
998 | dio->waiter = NULL; | 993 | dio->waiter = NULL; |
999 | 994 | ||
@@ -1069,6 +1064,9 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1069 | if (dio->bio) | 1064 | if (dio->bio) |
1070 | dio_bio_submit(dio); | 1065 | dio_bio_submit(dio); |
1071 | 1066 | ||
1067 | /* All IO is now issued, send it on its way */ | ||
1068 | blk_run_address_space(inode->i_mapping); | ||
1069 | |||
1072 | /* | 1070 | /* |
1073 | * It is possible that, we return short IO due to end of file. | 1071 | * It is possible that, we return short IO due to end of file. |
1074 | * In that case, we need to release all the pages we got hold on. | 1072 | * In that case, we need to release all the pages we got hold on. |
@@ -1084,74 +1082,41 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1084 | mutex_unlock(&dio->inode->i_mutex); | 1082 | mutex_unlock(&dio->inode->i_mutex); |
1085 | 1083 | ||
1086 | /* | 1084 | /* |
1087 | * OK, all BIOs are submitted, so we can decrement bio_count to truly | 1085 | * The only time we want to leave bios in flight is when a successful |
1088 | * reflect the number of to-be-processed BIOs. | 1086 | * partial aio read or full aio write have been setup. In that case |
1087 | * bio completion will call aio_complete. The only time it's safe to | ||
1088 | * call aio_complete is when we return -EIOCBQUEUED, so we key on that. | ||
1089 | * This had *better* be the only place that raises -EIOCBQUEUED. | ||
1089 | */ | 1090 | */ |
1090 | if (dio->is_async) { | 1091 | BUG_ON(ret == -EIOCBQUEUED); |
1091 | int should_wait = 0; | 1092 | if (dio->is_async && ret == 0 && dio->result && |
1093 | ((rw & READ) || (dio->result == dio->size))) | ||
1094 | ret = -EIOCBQUEUED; | ||
1092 | 1095 | ||
1093 | if (dio->result < dio->size && (rw & WRITE)) { | 1096 | if (ret != -EIOCBQUEUED) |
1094 | dio->waiter = current; | 1097 | dio_await_completion(dio); |
1095 | should_wait = 1; | ||
1096 | } | ||
1097 | if (ret == 0) | ||
1098 | ret = dio->result; | ||
1099 | finished_one_bio(dio); /* This can free the dio */ | ||
1100 | blk_run_address_space(inode->i_mapping); | ||
1101 | if (should_wait) { | ||
1102 | unsigned long flags; | ||
1103 | /* | ||
1104 | * Wait for already issued I/O to drain out and | ||
1105 | * release its references to user-space pages | ||
1106 | * before returning to fallback on buffered I/O | ||
1107 | */ | ||
1108 | |||
1109 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
1110 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1111 | while (dio->bio_count) { | ||
1112 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
1113 | io_schedule(); | ||
1114 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
1115 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1116 | } | ||
1117 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
1118 | set_current_state(TASK_RUNNING); | ||
1119 | kfree(dio); | ||
1120 | } | ||
1121 | } else { | ||
1122 | ssize_t transferred = 0; | ||
1123 | |||
1124 | finished_one_bio(dio); | ||
1125 | ret2 = dio_await_completion(dio); | ||
1126 | if (ret == 0) | ||
1127 | ret = ret2; | ||
1128 | if (ret == 0) | ||
1129 | ret = dio->page_errors; | ||
1130 | if (dio->result) { | ||
1131 | loff_t i_size = i_size_read(inode); | ||
1132 | |||
1133 | transferred = dio->result; | ||
1134 | /* | ||
1135 | * Adjust the return value if the read crossed a | ||
1136 | * non-block-aligned EOF. | ||
1137 | */ | ||
1138 | if (rw == READ && (offset + transferred > i_size)) | ||
1139 | transferred = i_size - offset; | ||
1140 | } | ||
1141 | dio_complete(dio, offset, transferred); | ||
1142 | if (ret == 0) | ||
1143 | ret = transferred; | ||
1144 | 1098 | ||
1145 | /* We could have also come here on an AIO file extend */ | 1099 | /* |
1146 | if (!is_sync_kiocb(iocb) && (rw & WRITE) && | 1100 | * Sync will always be dropping the final ref and completing the |
1147 | ret >= 0 && dio->result == dio->size) | 1101 | * operation. AIO can if it was a broken operation described above or |
1148 | /* | 1102 | * in fact if all the bios race to complete before we get here. In |
1149 | * For AIO writes where we have completed the | 1103 | * that case dio_complete() translates the EIOCBQUEUED into the proper |
1150 | * i/o, we have to mark the the aio complete. | 1104 | * return code that the caller will hand to aio_complete(). |
1151 | */ | 1105 | * |
1152 | aio_complete(iocb, ret, 0); | 1106 | * This is managed by the bio_lock instead of being an atomic_t so that |
1107 | * completion paths can drop their ref and use the remaining count to | ||
1108 | * decide to wake the submission path atomically. | ||
1109 | */ | ||
1110 | spin_lock_irqsave(&dio->bio_lock, flags); | ||
1111 | ret2 = --dio->refcount; | ||
1112 | spin_unlock_irqrestore(&dio->bio_lock, flags); | ||
1113 | BUG_ON(!dio->is_async && ret2 != 0); | ||
1114 | if (ret2 == 0) { | ||
1115 | ret = dio_complete(dio, offset, ret); | ||
1153 | kfree(dio); | 1116 | kfree(dio); |
1154 | } | 1117 | } else |
1118 | BUG_ON(ret != -EIOCBQUEUED); | ||
1119 | |||
1155 | return ret; | 1120 | return ret; |
1156 | } | 1121 | } |
1157 | 1122 | ||
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig index 81b2c6465eeb..b5654a284fef 100644 --- a/fs/dlm/Kconfig +++ b/fs/dlm/Kconfig | |||
@@ -1,14 +1,32 @@ | |||
1 | menu "Distributed Lock Manager" | 1 | menu "Distributed Lock Manager" |
2 | depends on INET && IP_SCTP && EXPERIMENTAL | 2 | depends on EXPERIMENTAL && INET |
3 | 3 | ||
4 | config DLM | 4 | config DLM |
5 | tristate "Distributed Lock Manager (DLM)" | 5 | tristate "Distributed Lock Manager (DLM)" |
6 | depends on IPV6 || IPV6=n | 6 | depends on IPV6 || IPV6=n |
7 | select CONFIGFS_FS | 7 | select CONFIGFS_FS |
8 | select IP_SCTP if DLM_SCTP | ||
8 | help | 9 | help |
9 | A general purpose distributed lock manager for kernel or userspace | 10 | A general purpose distributed lock manager for kernel or userspace |
10 | applications. | 11 | applications. |
11 | 12 | ||
13 | choice | ||
14 | prompt "Select DLM communications protocol" | ||
15 | depends on DLM | ||
16 | default DLM_TCP | ||
17 | help | ||
18 | The DLM Can use TCP or SCTP for it's network communications. | ||
19 | SCTP supports multi-homed operations whereas TCP doesn't. | ||
20 | However, SCTP seems to have stability problems at the moment. | ||
21 | |||
22 | config DLM_TCP | ||
23 | bool "TCP/IP" | ||
24 | |||
25 | config DLM_SCTP | ||
26 | bool "SCTP" | ||
27 | |||
28 | endchoice | ||
29 | |||
12 | config DLM_DEBUG | 30 | config DLM_DEBUG |
13 | bool "DLM debugging" | 31 | bool "DLM debugging" |
14 | depends on DLM | 32 | depends on DLM |
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile index 1832e0297f7d..65388944eba0 100644 --- a/fs/dlm/Makefile +++ b/fs/dlm/Makefile | |||
@@ -4,7 +4,6 @@ dlm-y := ast.o \ | |||
4 | dir.o \ | 4 | dir.o \ |
5 | lock.o \ | 5 | lock.o \ |
6 | lockspace.o \ | 6 | lockspace.o \ |
7 | lowcomms.o \ | ||
8 | main.o \ | 7 | main.o \ |
9 | member.o \ | 8 | member.o \ |
10 | memory.o \ | 9 | memory.o \ |
@@ -17,3 +16,6 @@ dlm-y := ast.o \ | |||
17 | util.o | 16 | util.o |
18 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o | 17 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o |
19 | 18 | ||
19 | dlm-$(CONFIG_DLM_TCP) += lowcomms-tcp.o | ||
20 | |||
21 | dlm-$(CONFIG_DLM_SCTP) += lowcomms-sctp.o \ No newline at end of file | ||
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 1e5cd67e1b7a..1ee8195e6fc0 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -471,6 +471,7 @@ struct dlm_ls { | |||
471 | char *ls_recover_buf; | 471 | char *ls_recover_buf; |
472 | int ls_recover_nodeid; /* for debugging */ | 472 | int ls_recover_nodeid; /* for debugging */ |
473 | uint64_t ls_rcom_seq; | 473 | uint64_t ls_rcom_seq; |
474 | spinlock_t ls_rcom_spin; | ||
474 | struct list_head ls_recover_list; | 475 | struct list_head ls_recover_list; |
475 | spinlock_t ls_recover_list_lock; | 476 | spinlock_t ls_recover_list_lock; |
476 | int ls_recover_list_count; | 477 | int ls_recover_list_count; |
@@ -488,7 +489,8 @@ struct dlm_ls { | |||
488 | #define LSFL_RUNNING 1 | 489 | #define LSFL_RUNNING 1 |
489 | #define LSFL_RECOVERY_STOP 2 | 490 | #define LSFL_RECOVERY_STOP 2 |
490 | #define LSFL_RCOM_READY 3 | 491 | #define LSFL_RCOM_READY 3 |
491 | #define LSFL_UEVENT_WAIT 4 | 492 | #define LSFL_RCOM_WAIT 4 |
493 | #define LSFL_UEVENT_WAIT 5 | ||
492 | 494 | ||
493 | /* much of this is just saving user space pointers associated with the | 495 | /* much of this is just saving user space pointers associated with the |
494 | lock that we pass back to the user lib with an ast */ | 496 | lock that we pass back to the user lib with an ast */ |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 3f2befa4797b..30878defaeb6 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -2372,6 +2372,7 @@ static int send_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms_in, | |||
2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) | 2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) |
2373 | { | 2373 | { |
2374 | lkb->lkb_exflags = ms->m_exflags; | 2374 | lkb->lkb_exflags = ms->m_exflags; |
2375 | lkb->lkb_sbflags = ms->m_sbflags; | ||
2375 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | | 2376 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | |
2376 | (ms->m_flags & 0x0000FFFF); | 2377 | (ms->m_flags & 0x0000FFFF); |
2377 | } | 2378 | } |
@@ -3028,10 +3029,17 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) | |||
3028 | 3029 | ||
3029 | while (1) { | 3030 | while (1) { |
3030 | if (dlm_locking_stopped(ls)) { | 3031 | if (dlm_locking_stopped(ls)) { |
3031 | if (!recovery) | 3032 | if (recovery) { |
3032 | dlm_add_requestqueue(ls, nodeid, hd); | 3033 | error = -EINTR; |
3033 | error = -EINTR; | 3034 | goto out; |
3034 | goto out; | 3035 | } |
3036 | error = dlm_add_requestqueue(ls, nodeid, hd); | ||
3037 | if (error == -EAGAIN) | ||
3038 | continue; | ||
3039 | else { | ||
3040 | error = -EINTR; | ||
3041 | goto out; | ||
3042 | } | ||
3035 | } | 3043 | } |
3036 | 3044 | ||
3037 | if (lock_recovery_try(ls)) | 3045 | if (lock_recovery_try(ls)) |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index f8842ca443c2..59012b089e8d 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "memory.h" | 22 | #include "memory.h" |
23 | #include "lock.h" | 23 | #include "lock.h" |
24 | #include "recover.h" | 24 | #include "recover.h" |
25 | #include "requestqueue.h" | ||
25 | 26 | ||
26 | #ifdef CONFIG_DLM_DEBUG | 27 | #ifdef CONFIG_DLM_DEBUG |
27 | int dlm_create_debug_file(struct dlm_ls *ls); | 28 | int dlm_create_debug_file(struct dlm_ls *ls); |
@@ -478,6 +479,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
478 | ls->ls_recoverd_task = NULL; | 479 | ls->ls_recoverd_task = NULL; |
479 | mutex_init(&ls->ls_recoverd_active); | 480 | mutex_init(&ls->ls_recoverd_active); |
480 | spin_lock_init(&ls->ls_recover_lock); | 481 | spin_lock_init(&ls->ls_recover_lock); |
482 | spin_lock_init(&ls->ls_rcom_spin); | ||
483 | get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t)); | ||
481 | ls->ls_recover_status = 0; | 484 | ls->ls_recover_status = 0; |
482 | ls->ls_recover_seq = 0; | 485 | ls->ls_recover_seq = 0; |
483 | ls->ls_recover_args = NULL; | 486 | ls->ls_recover_args = NULL; |
@@ -684,6 +687,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
684 | * Free structures on any other lists | 687 | * Free structures on any other lists |
685 | */ | 688 | */ |
686 | 689 | ||
690 | dlm_purge_requestqueue(ls); | ||
687 | kfree(ls->ls_recover_args); | 691 | kfree(ls->ls_recover_args); |
688 | dlm_clear_free_entries(ls); | 692 | dlm_clear_free_entries(ls); |
689 | dlm_clear_members(ls); | 693 | dlm_clear_members(ls); |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms-sctp.c index 6da6b14d5a61..fe158d7a9285 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms-sctp.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -75,13 +75,13 @@ struct nodeinfo { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | static DEFINE_IDR(nodeinfo_idr); | 77 | static DEFINE_IDR(nodeinfo_idr); |
78 | static struct rw_semaphore nodeinfo_lock; | 78 | static DECLARE_RWSEM(nodeinfo_lock); |
79 | static int max_nodeid; | 79 | static int max_nodeid; |
80 | 80 | ||
81 | struct cbuf { | 81 | struct cbuf { |
82 | unsigned base; | 82 | unsigned int base; |
83 | unsigned len; | 83 | unsigned int len; |
84 | unsigned mask; | 84 | unsigned int mask; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Just the one of these, now. But this struct keeps | 87 | /* Just the one of these, now. But this struct keeps |
@@ -90,9 +90,9 @@ struct cbuf { | |||
90 | #define CF_READ_PENDING 1 | 90 | #define CF_READ_PENDING 1 |
91 | 91 | ||
92 | struct connection { | 92 | struct connection { |
93 | struct socket *sock; | 93 | struct socket *sock; |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | struct page *rx_page; | 95 | struct page *rx_page; |
96 | atomic_t waiting_requests; | 96 | atomic_t waiting_requests; |
97 | struct cbuf cb; | 97 | struct cbuf cb; |
98 | int eagain_flag; | 98 | int eagain_flag; |
@@ -102,36 +102,40 @@ struct connection { | |||
102 | 102 | ||
103 | struct writequeue_entry { | 103 | struct writequeue_entry { |
104 | struct list_head list; | 104 | struct list_head list; |
105 | struct page *page; | 105 | struct page *page; |
106 | int offset; | 106 | int offset; |
107 | int len; | 107 | int len; |
108 | int end; | 108 | int end; |
109 | int users; | 109 | int users; |
110 | struct nodeinfo *ni; | 110 | struct nodeinfo *ni; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | #define CBUF_ADD(cb, n) do { (cb)->len += n; } while(0) | 113 | static void cbuf_add(struct cbuf *cb, int n) |
114 | #define CBUF_EMPTY(cb) ((cb)->len == 0) | 114 | { |
115 | #define CBUF_MAY_ADD(cb, n) (((cb)->len + (n)) < ((cb)->mask + 1)) | 115 | cb->len += n; |
116 | #define CBUF_DATA(cb) (((cb)->base + (cb)->len) & (cb)->mask) | 116 | } |
117 | 117 | ||
118 | #define CBUF_INIT(cb, size) \ | 118 | static int cbuf_data(struct cbuf *cb) |
119 | do { \ | 119 | { |
120 | (cb)->base = (cb)->len = 0; \ | 120 | return ((cb->base + cb->len) & cb->mask); |
121 | (cb)->mask = ((size)-1); \ | 121 | } |
122 | } while(0) | ||
123 | 122 | ||
124 | #define CBUF_EAT(cb, n) \ | 123 | static void cbuf_init(struct cbuf *cb, int size) |
125 | do { \ | 124 | { |
126 | (cb)->len -= (n); \ | 125 | cb->base = cb->len = 0; |
127 | (cb)->base += (n); \ | 126 | cb->mask = size-1; |
128 | (cb)->base &= (cb)->mask; \ | 127 | } |
129 | } while(0) | ||
130 | 128 | ||
129 | static void cbuf_eat(struct cbuf *cb, int n) | ||
130 | { | ||
131 | cb->len -= n; | ||
132 | cb->base += n; | ||
133 | cb->base &= cb->mask; | ||
134 | } | ||
131 | 135 | ||
132 | /* List of nodes which have writes pending */ | 136 | /* List of nodes which have writes pending */ |
133 | static struct list_head write_nodes; | 137 | static LIST_HEAD(write_nodes); |
134 | static spinlock_t write_nodes_lock; | 138 | static DEFINE_SPINLOCK(write_nodes_lock); |
135 | 139 | ||
136 | /* Maximum number of incoming messages to process before | 140 | /* Maximum number of incoming messages to process before |
137 | * doing a schedule() | 141 | * doing a schedule() |
@@ -141,8 +145,7 @@ static spinlock_t write_nodes_lock; | |||
141 | /* Manage daemons */ | 145 | /* Manage daemons */ |
142 | static struct task_struct *recv_task; | 146 | static struct task_struct *recv_task; |
143 | static struct task_struct *send_task; | 147 | static struct task_struct *send_task; |
144 | static wait_queue_head_t lowcomms_recv_wait; | 148 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_wait); |
145 | static atomic_t accepting; | ||
146 | 149 | ||
147 | /* The SCTP connection */ | 150 | /* The SCTP connection */ |
148 | static struct connection sctp_con; | 151 | static struct connection sctp_con; |
@@ -161,11 +164,11 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
161 | return error; | 164 | return error; |
162 | 165 | ||
163 | if (dlm_local_addr[0]->ss_family == AF_INET) { | 166 | if (dlm_local_addr[0]->ss_family == AF_INET) { |
164 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; | 167 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; |
165 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; | 168 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; |
166 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; | 169 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; |
167 | } else { | 170 | } else { |
168 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; | 171 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; |
169 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; | 172 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; |
170 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, | 173 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, |
171 | sizeof(in6->sin6_addr)); | 174 | sizeof(in6->sin6_addr)); |
@@ -174,6 +177,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
174 | return 0; | 177 | return 0; |
175 | } | 178 | } |
176 | 179 | ||
180 | /* If alloc is 0 here we will not attempt to allocate a new | ||
181 | nodeinfo struct */ | ||
177 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | 182 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) |
178 | { | 183 | { |
179 | struct nodeinfo *ni; | 184 | struct nodeinfo *ni; |
@@ -184,44 +189,45 @@ static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | |||
184 | ni = idr_find(&nodeinfo_idr, nodeid); | 189 | ni = idr_find(&nodeinfo_idr, nodeid); |
185 | up_read(&nodeinfo_lock); | 190 | up_read(&nodeinfo_lock); |
186 | 191 | ||
187 | if (!ni && alloc) { | 192 | if (ni || !alloc) |
188 | down_write(&nodeinfo_lock); | 193 | return ni; |
189 | 194 | ||
190 | ni = idr_find(&nodeinfo_idr, nodeid); | 195 | down_write(&nodeinfo_lock); |
191 | if (ni) | ||
192 | goto out_up; | ||
193 | 196 | ||
194 | r = idr_pre_get(&nodeinfo_idr, alloc); | 197 | ni = idr_find(&nodeinfo_idr, nodeid); |
195 | if (!r) | 198 | if (ni) |
196 | goto out_up; | 199 | goto out_up; |
197 | 200 | ||
198 | ni = kmalloc(sizeof(struct nodeinfo), alloc); | 201 | r = idr_pre_get(&nodeinfo_idr, alloc); |
199 | if (!ni) | 202 | if (!r) |
200 | goto out_up; | 203 | goto out_up; |
201 | 204 | ||
202 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); | 205 | ni = kmalloc(sizeof(struct nodeinfo), alloc); |
203 | if (r) { | 206 | if (!ni) |
204 | kfree(ni); | 207 | goto out_up; |
205 | ni = NULL; | 208 | |
206 | goto out_up; | 209 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); |
207 | } | 210 | if (r) { |
208 | if (n != nodeid) { | 211 | kfree(ni); |
209 | idr_remove(&nodeinfo_idr, n); | 212 | ni = NULL; |
210 | kfree(ni); | 213 | goto out_up; |
211 | ni = NULL; | ||
212 | goto out_up; | ||
213 | } | ||
214 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
215 | spin_lock_init(&ni->lock); | ||
216 | INIT_LIST_HEAD(&ni->writequeue); | ||
217 | spin_lock_init(&ni->writequeue_lock); | ||
218 | ni->nodeid = nodeid; | ||
219 | |||
220 | if (nodeid > max_nodeid) | ||
221 | max_nodeid = nodeid; | ||
222 | out_up: | ||
223 | up_write(&nodeinfo_lock); | ||
224 | } | 214 | } |
215 | if (n != nodeid) { | ||
216 | idr_remove(&nodeinfo_idr, n); | ||
217 | kfree(ni); | ||
218 | ni = NULL; | ||
219 | goto out_up; | ||
220 | } | ||
221 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
222 | spin_lock_init(&ni->lock); | ||
223 | INIT_LIST_HEAD(&ni->writequeue); | ||
224 | spin_lock_init(&ni->writequeue_lock); | ||
225 | ni->nodeid = nodeid; | ||
226 | |||
227 | if (nodeid > max_nodeid) | ||
228 | max_nodeid = nodeid; | ||
229 | out_up: | ||
230 | up_write(&nodeinfo_lock); | ||
225 | 231 | ||
226 | return ni; | 232 | return ni; |
227 | } | 233 | } |
@@ -279,13 +285,13 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | |||
279 | in4_addr->sin_port = cpu_to_be16(port); | 285 | in4_addr->sin_port = cpu_to_be16(port); |
280 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); | 286 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); |
281 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - | 287 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - |
282 | sizeof(struct sockaddr_in)); | 288 | sizeof(struct sockaddr_in)); |
283 | *addr_len = sizeof(struct sockaddr_in); | 289 | *addr_len = sizeof(struct sockaddr_in); |
284 | } else { | 290 | } else { |
285 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | 291 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; |
286 | in6_addr->sin6_port = cpu_to_be16(port); | 292 | in6_addr->sin6_port = cpu_to_be16(port); |
287 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - | 293 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - |
288 | sizeof(struct sockaddr_in6)); | 294 | sizeof(struct sockaddr_in6)); |
289 | *addr_len = sizeof(struct sockaddr_in6); | 295 | *addr_len = sizeof(struct sockaddr_in6); |
290 | } | 296 | } |
291 | } | 297 | } |
@@ -324,7 +330,7 @@ static void send_shutdown(sctp_assoc_t associd) | |||
324 | cmsg->cmsg_type = SCTP_SNDRCV; | 330 | cmsg->cmsg_type = SCTP_SNDRCV; |
325 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 331 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
326 | outmessage.msg_controllen = cmsg->cmsg_len; | 332 | outmessage.msg_controllen = cmsg->cmsg_len; |
327 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 333 | sinfo = CMSG_DATA(cmsg); |
328 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 334 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
329 | 335 | ||
330 | sinfo->sinfo_flags |= MSG_EOF; | 336 | sinfo->sinfo_flags |= MSG_EOF; |
@@ -387,7 +393,7 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
387 | 393 | ||
388 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { | 394 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { |
389 | log_print("COMM_UP for invalid assoc ID %d", | 395 | log_print("COMM_UP for invalid assoc ID %d", |
390 | (int)sn->sn_assoc_change.sac_assoc_id); | 396 | (int)sn->sn_assoc_change.sac_assoc_id); |
391 | init_failed(); | 397 | init_failed(); |
392 | return; | 398 | return; |
393 | } | 399 | } |
@@ -398,15 +404,18 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
398 | fs = get_fs(); | 404 | fs = get_fs(); |
399 | set_fs(get_ds()); | 405 | set_fs(get_ds()); |
400 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, | 406 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, |
401 | IPPROTO_SCTP, SCTP_PRIMARY_ADDR, | 407 | IPPROTO_SCTP, |
402 | (char*)&prim, &prim_len); | 408 | SCTP_PRIMARY_ADDR, |
409 | (char*)&prim, | ||
410 | &prim_len); | ||
403 | set_fs(fs); | 411 | set_fs(fs); |
404 | if (ret < 0) { | 412 | if (ret < 0) { |
405 | struct nodeinfo *ni; | 413 | struct nodeinfo *ni; |
406 | 414 | ||
407 | log_print("getsockopt/sctp_primary_addr on " | 415 | log_print("getsockopt/sctp_primary_addr on " |
408 | "new assoc %d failed : %d", | 416 | "new assoc %d failed : %d", |
409 | (int)sn->sn_assoc_change.sac_assoc_id, ret); | 417 | (int)sn->sn_assoc_change.sac_assoc_id, |
418 | ret); | ||
410 | 419 | ||
411 | /* Retry INIT later */ | 420 | /* Retry INIT later */ |
412 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); | 421 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); |
@@ -426,12 +435,10 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
426 | return; | 435 | return; |
427 | 436 | ||
428 | /* Save the assoc ID */ | 437 | /* Save the assoc ID */ |
429 | spin_lock(&ni->lock); | ||
430 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; | 438 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; |
431 | spin_unlock(&ni->lock); | ||
432 | 439 | ||
433 | log_print("got new/restarted association %d nodeid %d", | 440 | log_print("got new/restarted association %d nodeid %d", |
434 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); | 441 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); |
435 | 442 | ||
436 | /* Send any pending writes */ | 443 | /* Send any pending writes */ |
437 | clear_bit(NI_INIT_PENDING, &ni->flags); | 444 | clear_bit(NI_INIT_PENDING, &ni->flags); |
@@ -507,13 +514,12 @@ static int receive_from_sock(void) | |||
507 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); | 514 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); |
508 | if (sctp_con.rx_page == NULL) | 515 | if (sctp_con.rx_page == NULL) |
509 | goto out_resched; | 516 | goto out_resched; |
510 | CBUF_INIT(&sctp_con.cb, PAGE_CACHE_SIZE); | 517 | cbuf_init(&sctp_con.cb, PAGE_CACHE_SIZE); |
511 | } | 518 | } |
512 | 519 | ||
513 | memset(&incmsg, 0, sizeof(incmsg)); | 520 | memset(&incmsg, 0, sizeof(incmsg)); |
514 | memset(&msgname, 0, sizeof(msgname)); | 521 | memset(&msgname, 0, sizeof(msgname)); |
515 | 522 | ||
516 | memset(incmsg, 0, sizeof(incmsg)); | ||
517 | msg.msg_name = &msgname; | 523 | msg.msg_name = &msgname; |
518 | msg.msg_namelen = sizeof(msgname); | 524 | msg.msg_namelen = sizeof(msgname); |
519 | msg.msg_flags = 0; | 525 | msg.msg_flags = 0; |
@@ -532,17 +538,17 @@ static int receive_from_sock(void) | |||
532 | * iov[0] is the bit of the circular buffer between the current end | 538 | * iov[0] is the bit of the circular buffer between the current end |
533 | * point (cb.base + cb.len) and the end of the buffer. | 539 | * point (cb.base + cb.len) and the end of the buffer. |
534 | */ | 540 | */ |
535 | iov[0].iov_len = sctp_con.cb.base - CBUF_DATA(&sctp_con.cb); | 541 | iov[0].iov_len = sctp_con.cb.base - cbuf_data(&sctp_con.cb); |
536 | iov[0].iov_base = page_address(sctp_con.rx_page) + | 542 | iov[0].iov_base = page_address(sctp_con.rx_page) + |
537 | CBUF_DATA(&sctp_con.cb); | 543 | cbuf_data(&sctp_con.cb); |
538 | iov[1].iov_len = 0; | 544 | iov[1].iov_len = 0; |
539 | 545 | ||
540 | /* | 546 | /* |
541 | * iov[1] is the bit of the circular buffer between the start of the | 547 | * iov[1] is the bit of the circular buffer between the start of the |
542 | * buffer and the start of the currently used section (cb.base) | 548 | * buffer and the start of the currently used section (cb.base) |
543 | */ | 549 | */ |
544 | if (CBUF_DATA(&sctp_con.cb) >= sctp_con.cb.base) { | 550 | if (cbuf_data(&sctp_con.cb) >= sctp_con.cb.base) { |
545 | iov[0].iov_len = PAGE_CACHE_SIZE - CBUF_DATA(&sctp_con.cb); | 551 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&sctp_con.cb); |
546 | iov[1].iov_len = sctp_con.cb.base; | 552 | iov[1].iov_len = sctp_con.cb.base; |
547 | iov[1].iov_base = page_address(sctp_con.rx_page); | 553 | iov[1].iov_base = page_address(sctp_con.rx_page); |
548 | msg.msg_iovlen = 2; | 554 | msg.msg_iovlen = 2; |
@@ -557,7 +563,7 @@ static int receive_from_sock(void) | |||
557 | msg.msg_control = incmsg; | 563 | msg.msg_control = incmsg; |
558 | msg.msg_controllen = sizeof(incmsg); | 564 | msg.msg_controllen = sizeof(incmsg); |
559 | cmsg = CMSG_FIRSTHDR(&msg); | 565 | cmsg = CMSG_FIRSTHDR(&msg); |
560 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 566 | sinfo = CMSG_DATA(cmsg); |
561 | 567 | ||
562 | if (msg.msg_flags & MSG_NOTIFICATION) { | 568 | if (msg.msg_flags & MSG_NOTIFICATION) { |
563 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); | 569 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); |
@@ -583,29 +589,29 @@ static int receive_from_sock(void) | |||
583 | if (r == 1) | 589 | if (r == 1) |
584 | return 0; | 590 | return 0; |
585 | 591 | ||
586 | CBUF_ADD(&sctp_con.cb, ret); | 592 | cbuf_add(&sctp_con.cb, ret); |
587 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), | 593 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), |
588 | page_address(sctp_con.rx_page), | 594 | page_address(sctp_con.rx_page), |
589 | sctp_con.cb.base, sctp_con.cb.len, | 595 | sctp_con.cb.base, sctp_con.cb.len, |
590 | PAGE_CACHE_SIZE); | 596 | PAGE_CACHE_SIZE); |
591 | if (ret < 0) | 597 | if (ret < 0) |
592 | goto out_close; | 598 | goto out_close; |
593 | CBUF_EAT(&sctp_con.cb, ret); | 599 | cbuf_eat(&sctp_con.cb, ret); |
594 | 600 | ||
595 | out: | 601 | out: |
596 | ret = 0; | 602 | ret = 0; |
597 | goto out_ret; | 603 | goto out_ret; |
598 | 604 | ||
599 | out_resched: | 605 | out_resched: |
600 | lowcomms_data_ready(sctp_con.sock->sk, 0); | 606 | lowcomms_data_ready(sctp_con.sock->sk, 0); |
601 | ret = 0; | 607 | ret = 0; |
602 | schedule(); | 608 | cond_resched(); |
603 | goto out_ret; | 609 | goto out_ret; |
604 | 610 | ||
605 | out_close: | 611 | out_close: |
606 | if (ret != -EAGAIN) | 612 | if (ret != -EAGAIN) |
607 | log_print("error reading from sctp socket: %d", ret); | 613 | log_print("error reading from sctp socket: %d", ret); |
608 | out_ret: | 614 | out_ret: |
609 | return ret; | 615 | return ret; |
610 | } | 616 | } |
611 | 617 | ||
@@ -619,10 +625,12 @@ static int add_bind_addr(struct sockaddr_storage *addr, int addr_len, int num) | |||
619 | set_fs(get_ds()); | 625 | set_fs(get_ds()); |
620 | if (num == 1) | 626 | if (num == 1) |
621 | result = sctp_con.sock->ops->bind(sctp_con.sock, | 627 | result = sctp_con.sock->ops->bind(sctp_con.sock, |
622 | (struct sockaddr *) addr, addr_len); | 628 | (struct sockaddr *) addr, |
629 | addr_len); | ||
623 | else | 630 | else |
624 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, | 631 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, |
625 | SCTP_SOCKOPT_BINDX_ADD, (char *)addr, addr_len); | 632 | SCTP_SOCKOPT_BINDX_ADD, |
633 | (char *)addr, addr_len); | ||
626 | set_fs(fs); | 634 | set_fs(fs); |
627 | 635 | ||
628 | if (result < 0) | 636 | if (result < 0) |
@@ -719,10 +727,10 @@ static int init_sock(void) | |||
719 | 727 | ||
720 | return 0; | 728 | return 0; |
721 | 729 | ||
722 | create_delsock: | 730 | create_delsock: |
723 | sock_release(sock); | 731 | sock_release(sock); |
724 | sctp_con.sock = NULL; | 732 | sctp_con.sock = NULL; |
725 | out: | 733 | out: |
726 | return result; | 734 | return result; |
727 | } | 735 | } |
728 | 736 | ||
@@ -756,16 +764,13 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
756 | int users = 0; | 764 | int users = 0; |
757 | struct nodeinfo *ni; | 765 | struct nodeinfo *ni; |
758 | 766 | ||
759 | if (!atomic_read(&accepting)) | ||
760 | return NULL; | ||
761 | |||
762 | ni = nodeid2nodeinfo(nodeid, allocation); | 767 | ni = nodeid2nodeinfo(nodeid, allocation); |
763 | if (!ni) | 768 | if (!ni) |
764 | return NULL; | 769 | return NULL; |
765 | 770 | ||
766 | spin_lock(&ni->writequeue_lock); | 771 | spin_lock(&ni->writequeue_lock); |
767 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); | 772 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); |
768 | if (((struct list_head *) e == &ni->writequeue) || | 773 | if ((&e->list == &ni->writequeue) || |
769 | (PAGE_CACHE_SIZE - e->end < len)) { | 774 | (PAGE_CACHE_SIZE - e->end < len)) { |
770 | e = NULL; | 775 | e = NULL; |
771 | } else { | 776 | } else { |
@@ -776,7 +781,7 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
776 | spin_unlock(&ni->writequeue_lock); | 781 | spin_unlock(&ni->writequeue_lock); |
777 | 782 | ||
778 | if (e) { | 783 | if (e) { |
779 | got_one: | 784 | got_one: |
780 | if (users == 0) | 785 | if (users == 0) |
781 | kmap(e->page); | 786 | kmap(e->page); |
782 | *ppc = page_address(e->page) + offset; | 787 | *ppc = page_address(e->page) + offset; |
@@ -803,9 +808,6 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
803 | int users; | 808 | int users; |
804 | struct nodeinfo *ni = e->ni; | 809 | struct nodeinfo *ni = e->ni; |
805 | 810 | ||
806 | if (!atomic_read(&accepting)) | ||
807 | return; | ||
808 | |||
809 | spin_lock(&ni->writequeue_lock); | 811 | spin_lock(&ni->writequeue_lock); |
810 | users = --e->users; | 812 | users = --e->users; |
811 | if (users) | 813 | if (users) |
@@ -822,7 +824,7 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
822 | } | 824 | } |
823 | return; | 825 | return; |
824 | 826 | ||
825 | out: | 827 | out: |
826 | spin_unlock(&ni->writequeue_lock); | 828 | spin_unlock(&ni->writequeue_lock); |
827 | return; | 829 | return; |
828 | } | 830 | } |
@@ -878,7 +880,7 @@ static void initiate_association(int nodeid) | |||
878 | cmsg->cmsg_level = IPPROTO_SCTP; | 880 | cmsg->cmsg_level = IPPROTO_SCTP; |
879 | cmsg->cmsg_type = SCTP_SNDRCV; | 881 | cmsg->cmsg_type = SCTP_SNDRCV; |
880 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 882 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
881 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 883 | sinfo = CMSG_DATA(cmsg); |
882 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 884 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
883 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 885 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
884 | 886 | ||
@@ -892,7 +894,7 @@ static void initiate_association(int nodeid) | |||
892 | } | 894 | } |
893 | 895 | ||
894 | /* Send a message */ | 896 | /* Send a message */ |
895 | static int send_to_sock(struct nodeinfo *ni) | 897 | static void send_to_sock(struct nodeinfo *ni) |
896 | { | 898 | { |
897 | int ret = 0; | 899 | int ret = 0; |
898 | struct writequeue_entry *e; | 900 | struct writequeue_entry *e; |
@@ -903,13 +905,13 @@ static int send_to_sock(struct nodeinfo *ni) | |||
903 | struct sctp_sndrcvinfo *sinfo; | 905 | struct sctp_sndrcvinfo *sinfo; |
904 | struct kvec iov; | 906 | struct kvec iov; |
905 | 907 | ||
906 | /* See if we need to init an association before we start | 908 | /* See if we need to init an association before we start |
907 | sending precious messages */ | 909 | sending precious messages */ |
908 | spin_lock(&ni->lock); | 910 | spin_lock(&ni->lock); |
909 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 911 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
910 | spin_unlock(&ni->lock); | 912 | spin_unlock(&ni->lock); |
911 | initiate_association(ni->nodeid); | 913 | initiate_association(ni->nodeid); |
912 | return 0; | 914 | return; |
913 | } | 915 | } |
914 | spin_unlock(&ni->lock); | 916 | spin_unlock(&ni->lock); |
915 | 917 | ||
@@ -923,7 +925,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
923 | cmsg->cmsg_level = IPPROTO_SCTP; | 925 | cmsg->cmsg_level = IPPROTO_SCTP; |
924 | cmsg->cmsg_type = SCTP_SNDRCV; | 926 | cmsg->cmsg_type = SCTP_SNDRCV; |
925 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 927 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
926 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 928 | sinfo = CMSG_DATA(cmsg); |
927 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 929 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
928 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 930 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
929 | sinfo->sinfo_assoc_id = ni->assoc_id; | 931 | sinfo->sinfo_assoc_id = ni->assoc_id; |
@@ -955,7 +957,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
955 | goto send_error; | 957 | goto send_error; |
956 | } else { | 958 | } else { |
957 | /* Don't starve people filling buffers */ | 959 | /* Don't starve people filling buffers */ |
958 | schedule(); | 960 | cond_resched(); |
959 | } | 961 | } |
960 | 962 | ||
961 | spin_lock(&ni->writequeue_lock); | 963 | spin_lock(&ni->writequeue_lock); |
@@ -964,15 +966,16 @@ static int send_to_sock(struct nodeinfo *ni) | |||
964 | 966 | ||
965 | if (e->len == 0 && e->users == 0) { | 967 | if (e->len == 0 && e->users == 0) { |
966 | list_del(&e->list); | 968 | list_del(&e->list); |
969 | kunmap(e->page); | ||
967 | free_entry(e); | 970 | free_entry(e); |
968 | continue; | 971 | continue; |
969 | } | 972 | } |
970 | } | 973 | } |
971 | spin_unlock(&ni->writequeue_lock); | 974 | spin_unlock(&ni->writequeue_lock); |
972 | out: | 975 | out: |
973 | return ret; | 976 | return; |
974 | 977 | ||
975 | send_error: | 978 | send_error: |
976 | log_print("Error sending to node %d %d", ni->nodeid, ret); | 979 | log_print("Error sending to node %d %d", ni->nodeid, ret); |
977 | spin_lock(&ni->lock); | 980 | spin_lock(&ni->lock); |
978 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 981 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
@@ -982,7 +985,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
982 | } else | 985 | } else |
983 | spin_unlock(&ni->lock); | 986 | spin_unlock(&ni->lock); |
984 | 987 | ||
985 | return ret; | 988 | return; |
986 | } | 989 | } |
987 | 990 | ||
988 | /* Try to send any messages that are pending */ | 991 | /* Try to send any messages that are pending */ |
@@ -994,7 +997,7 @@ static void process_output_queue(void) | |||
994 | spin_lock_bh(&write_nodes_lock); | 997 | spin_lock_bh(&write_nodes_lock); |
995 | list_for_each_safe(list, temp, &write_nodes) { | 998 | list_for_each_safe(list, temp, &write_nodes) { |
996 | struct nodeinfo *ni = | 999 | struct nodeinfo *ni = |
997 | list_entry(list, struct nodeinfo, write_list); | 1000 | list_entry(list, struct nodeinfo, write_list); |
998 | clear_bit(NI_WRITE_PENDING, &ni->flags); | 1001 | clear_bit(NI_WRITE_PENDING, &ni->flags); |
999 | list_del(&ni->write_list); | 1002 | list_del(&ni->write_list); |
1000 | 1003 | ||
@@ -1106,7 +1109,7 @@ static int dlm_recvd(void *data) | |||
1106 | set_current_state(TASK_INTERRUPTIBLE); | 1109 | set_current_state(TASK_INTERRUPTIBLE); |
1107 | add_wait_queue(&lowcomms_recv_wait, &wait); | 1110 | add_wait_queue(&lowcomms_recv_wait, &wait); |
1108 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) | 1111 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) |
1109 | schedule(); | 1112 | cond_resched(); |
1110 | remove_wait_queue(&lowcomms_recv_wait, &wait); | 1113 | remove_wait_queue(&lowcomms_recv_wait, &wait); |
1111 | set_current_state(TASK_RUNNING); | 1114 | set_current_state(TASK_RUNNING); |
1112 | 1115 | ||
@@ -1118,12 +1121,12 @@ static int dlm_recvd(void *data) | |||
1118 | 1121 | ||
1119 | /* Don't starve out everyone else */ | 1122 | /* Don't starve out everyone else */ |
1120 | if (++count >= MAX_RX_MSG_COUNT) { | 1123 | if (++count >= MAX_RX_MSG_COUNT) { |
1121 | schedule(); | 1124 | cond_resched(); |
1122 | count = 0; | 1125 | count = 0; |
1123 | } | 1126 | } |
1124 | } while (!kthread_should_stop() && ret >=0); | 1127 | } while (!kthread_should_stop() && ret >=0); |
1125 | } | 1128 | } |
1126 | schedule(); | 1129 | cond_resched(); |
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | return 0; | 1132 | return 0; |
@@ -1138,7 +1141,7 @@ static int dlm_sendd(void *data) | |||
1138 | while (!kthread_should_stop()) { | 1141 | while (!kthread_should_stop()) { |
1139 | set_current_state(TASK_INTERRUPTIBLE); | 1142 | set_current_state(TASK_INTERRUPTIBLE); |
1140 | if (write_list_empty()) | 1143 | if (write_list_empty()) |
1141 | schedule(); | 1144 | cond_resched(); |
1142 | set_current_state(TASK_RUNNING); | 1145 | set_current_state(TASK_RUNNING); |
1143 | 1146 | ||
1144 | if (sctp_con.eagain_flag) { | 1147 | if (sctp_con.eagain_flag) { |
@@ -1166,7 +1169,7 @@ static int daemons_start(void) | |||
1166 | 1169 | ||
1167 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | 1170 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); |
1168 | error = IS_ERR(p); | 1171 | error = IS_ERR(p); |
1169 | if (error) { | 1172 | if (error) { |
1170 | log_print("can't start dlm_recvd %d", error); | 1173 | log_print("can't start dlm_recvd %d", error); |
1171 | return error; | 1174 | return error; |
1172 | } | 1175 | } |
@@ -1174,7 +1177,7 @@ static int daemons_start(void) | |||
1174 | 1177 | ||
1175 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | 1178 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); |
1176 | error = IS_ERR(p); | 1179 | error = IS_ERR(p); |
1177 | if (error) { | 1180 | if (error) { |
1178 | log_print("can't start dlm_sendd %d", error); | 1181 | log_print("can't start dlm_sendd %d", error); |
1179 | kthread_stop(recv_task); | 1182 | kthread_stop(recv_task); |
1180 | return error; | 1183 | return error; |
@@ -1197,43 +1200,28 @@ int dlm_lowcomms_start(void) | |||
1197 | error = daemons_start(); | 1200 | error = daemons_start(); |
1198 | if (error) | 1201 | if (error) |
1199 | goto fail_sock; | 1202 | goto fail_sock; |
1200 | atomic_set(&accepting, 1); | ||
1201 | return 0; | 1203 | return 0; |
1202 | 1204 | ||
1203 | fail_sock: | 1205 | fail_sock: |
1204 | close_connection(); | 1206 | close_connection(); |
1205 | return error; | 1207 | return error; |
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | /* Set all the activity flags to prevent any socket activity. */ | ||
1209 | |||
1210 | void dlm_lowcomms_stop(void) | 1210 | void dlm_lowcomms_stop(void) |
1211 | { | 1211 | { |
1212 | atomic_set(&accepting, 0); | 1212 | int i; |
1213 | |||
1213 | sctp_con.flags = 0x7; | 1214 | sctp_con.flags = 0x7; |
1214 | daemons_stop(); | 1215 | daemons_stop(); |
1215 | clean_writequeues(); | 1216 | clean_writequeues(); |
1216 | close_connection(); | 1217 | close_connection(); |
1217 | dealloc_nodeinfo(); | 1218 | dealloc_nodeinfo(); |
1218 | max_nodeid = 0; | 1219 | max_nodeid = 0; |
1219 | } | ||
1220 | 1220 | ||
1221 | int dlm_lowcomms_init(void) | 1221 | dlm_local_count = 0; |
1222 | { | 1222 | dlm_local_nodeid = 0; |
1223 | init_waitqueue_head(&lowcomms_recv_wait); | ||
1224 | spin_lock_init(&write_nodes_lock); | ||
1225 | INIT_LIST_HEAD(&write_nodes); | ||
1226 | init_rwsem(&nodeinfo_lock); | ||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | void dlm_lowcomms_exit(void) | ||
1231 | { | ||
1232 | int i; | ||
1233 | 1223 | ||
1234 | for (i = 0; i < dlm_local_count; i++) | 1224 | for (i = 0; i < dlm_local_count; i++) |
1235 | kfree(dlm_local_addr[i]); | 1225 | kfree(dlm_local_addr[i]); |
1236 | dlm_local_count = 0; | ||
1237 | dlm_local_nodeid = 0; | ||
1238 | } | 1226 | } |
1239 | 1227 | ||
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c new file mode 100644 index 000000000000..9be3a440c42a --- /dev/null +++ b/fs/dlm/lowcomms-tcp.c | |||
@@ -0,0 +1,1189 @@ | |||
1 | /****************************************************************************** | ||
2 | ******************************************************************************* | ||
3 | ** | ||
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
6 | ** | ||
7 | ** This copyrighted material is made available to anyone wishing to use, | ||
8 | ** modify, copy, or redistribute it subject to the terms and conditions | ||
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | |||
14 | /* | ||
15 | * lowcomms.c | ||
16 | * | ||
17 | * This is the "low-level" comms layer. | ||
18 | * | ||
19 | * It is responsible for sending/receiving messages | ||
20 | * from other nodes in the cluster. | ||
21 | * | ||
22 | * Cluster nodes are referred to by their nodeids. nodeids are | ||
23 | * simply 32 bit numbers to the locking module - if they need to | ||
24 | * be expanded for the cluster infrastructure then that is it's | ||
25 | * responsibility. It is this layer's | ||
26 | * responsibility to resolve these into IP address or | ||
27 | * whatever it needs for inter-node communication. | ||
28 | * | ||
29 | * The comms level is two kernel threads that deal mainly with | ||
30 | * the receiving of messages from other nodes and passing them | ||
31 | * up to the mid-level comms layer (which understands the | ||
32 | * message format) for execution by the locking core, and | ||
33 | * a send thread which does all the setting up of connections | ||
34 | * to remote nodes and the sending of data. Threads are not allowed | ||
35 | * to send their own data because it may cause them to wait in times | ||
36 | * of high load. Also, this way, the sending thread can collect together | ||
37 | * messages bound for one node and send them in one block. | ||
38 | * | ||
39 | * I don't see any problem with the recv thread executing the locking | ||
40 | * code on behalf of remote processes as the locking code is | ||
41 | * short, efficient and never waits. | ||
42 | * | ||
43 | */ | ||
44 | |||
45 | |||
46 | #include <asm/ioctls.h> | ||
47 | #include <net/sock.h> | ||
48 | #include <net/tcp.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | |||
51 | #include "dlm_internal.h" | ||
52 | #include "lowcomms.h" | ||
53 | #include "midcomms.h" | ||
54 | #include "config.h" | ||
55 | |||
56 | struct cbuf { | ||
57 | unsigned int base; | ||
58 | unsigned int len; | ||
59 | unsigned int mask; | ||
60 | }; | ||
61 | |||
62 | #define NODE_INCREMENT 32 | ||
63 | static void cbuf_add(struct cbuf *cb, int n) | ||
64 | { | ||
65 | cb->len += n; | ||
66 | } | ||
67 | |||
68 | static int cbuf_data(struct cbuf *cb) | ||
69 | { | ||
70 | return ((cb->base + cb->len) & cb->mask); | ||
71 | } | ||
72 | |||
73 | static void cbuf_init(struct cbuf *cb, int size) | ||
74 | { | ||
75 | cb->base = cb->len = 0; | ||
76 | cb->mask = size-1; | ||
77 | } | ||
78 | |||
79 | static void cbuf_eat(struct cbuf *cb, int n) | ||
80 | { | ||
81 | cb->len -= n; | ||
82 | cb->base += n; | ||
83 | cb->base &= cb->mask; | ||
84 | } | ||
85 | |||
86 | static bool cbuf_empty(struct cbuf *cb) | ||
87 | { | ||
88 | return cb->len == 0; | ||
89 | } | ||
90 | |||
91 | /* Maximum number of incoming messages to process before | ||
92 | doing a cond_resched() | ||
93 | */ | ||
94 | #define MAX_RX_MSG_COUNT 25 | ||
95 | |||
96 | struct connection { | ||
97 | struct socket *sock; /* NULL if not connected */ | ||
98 | uint32_t nodeid; /* So we know who we are in the list */ | ||
99 | struct rw_semaphore sock_sem; /* Stop connect races */ | ||
100 | struct list_head read_list; /* On this list when ready for reading */ | ||
101 | struct list_head write_list; /* On this list when ready for writing */ | ||
102 | struct list_head state_list; /* On this list when ready to connect */ | ||
103 | unsigned long flags; /* bit 1,2 = We are on the read/write lists */ | ||
104 | #define CF_READ_PENDING 1 | ||
105 | #define CF_WRITE_PENDING 2 | ||
106 | #define CF_CONNECT_PENDING 3 | ||
107 | #define CF_IS_OTHERCON 4 | ||
108 | struct list_head writequeue; /* List of outgoing writequeue_entries */ | ||
109 | struct list_head listenlist; /* List of allocated listening sockets */ | ||
110 | spinlock_t writequeue_lock; | ||
111 | int (*rx_action) (struct connection *); /* What to do when active */ | ||
112 | struct page *rx_page; | ||
113 | struct cbuf cb; | ||
114 | int retries; | ||
115 | atomic_t waiting_requests; | ||
116 | #define MAX_CONNECT_RETRIES 3 | ||
117 | struct connection *othercon; | ||
118 | }; | ||
119 | #define sock2con(x) ((struct connection *)(x)->sk_user_data) | ||
120 | |||
121 | /* An entry waiting to be sent */ | ||
122 | struct writequeue_entry { | ||
123 | struct list_head list; | ||
124 | struct page *page; | ||
125 | int offset; | ||
126 | int len; | ||
127 | int end; | ||
128 | int users; | ||
129 | struct connection *con; | ||
130 | }; | ||
131 | |||
132 | static struct sockaddr_storage dlm_local_addr; | ||
133 | |||
134 | /* Manage daemons */ | ||
135 | static struct task_struct *recv_task; | ||
136 | static struct task_struct *send_task; | ||
137 | |||
138 | static wait_queue_t lowcomms_send_waitq_head; | ||
139 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_send_waitq); | ||
140 | static wait_queue_t lowcomms_recv_waitq_head; | ||
141 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_waitq); | ||
142 | |||
143 | /* An array of pointers to connections, indexed by NODEID */ | ||
144 | static struct connection **connections; | ||
145 | static DECLARE_MUTEX(connections_lock); | ||
146 | static struct kmem_cache *con_cache; | ||
147 | static int conn_array_size; | ||
148 | |||
149 | /* List of sockets that have reads pending */ | ||
150 | static LIST_HEAD(read_sockets); | ||
151 | static DEFINE_SPINLOCK(read_sockets_lock); | ||
152 | |||
153 | /* List of sockets which have writes pending */ | ||
154 | static LIST_HEAD(write_sockets); | ||
155 | static DEFINE_SPINLOCK(write_sockets_lock); | ||
156 | |||
157 | /* List of sockets which have connects pending */ | ||
158 | static LIST_HEAD(state_sockets); | ||
159 | static DEFINE_SPINLOCK(state_sockets_lock); | ||
160 | |||
161 | static struct connection *nodeid2con(int nodeid, gfp_t allocation) | ||
162 | { | ||
163 | struct connection *con = NULL; | ||
164 | |||
165 | down(&connections_lock); | ||
166 | if (nodeid >= conn_array_size) { | ||
167 | int new_size = nodeid + NODE_INCREMENT; | ||
168 | struct connection **new_conns; | ||
169 | |||
170 | new_conns = kzalloc(sizeof(struct connection *) * | ||
171 | new_size, allocation); | ||
172 | if (!new_conns) | ||
173 | goto finish; | ||
174 | |||
175 | memcpy(new_conns, connections, sizeof(struct connection *) * conn_array_size); | ||
176 | conn_array_size = new_size; | ||
177 | kfree(connections); | ||
178 | connections = new_conns; | ||
179 | |||
180 | } | ||
181 | |||
182 | con = connections[nodeid]; | ||
183 | if (con == NULL && allocation) { | ||
184 | con = kmem_cache_zalloc(con_cache, allocation); | ||
185 | if (!con) | ||
186 | goto finish; | ||
187 | |||
188 | con->nodeid = nodeid; | ||
189 | init_rwsem(&con->sock_sem); | ||
190 | INIT_LIST_HEAD(&con->writequeue); | ||
191 | spin_lock_init(&con->writequeue_lock); | ||
192 | |||
193 | connections[nodeid] = con; | ||
194 | } | ||
195 | |||
196 | finish: | ||
197 | up(&connections_lock); | ||
198 | return con; | ||
199 | } | ||
200 | |||
201 | /* Data available on socket or listen socket received a connect */ | ||
202 | static void lowcomms_data_ready(struct sock *sk, int count_unused) | ||
203 | { | ||
204 | struct connection *con = sock2con(sk); | ||
205 | |||
206 | atomic_inc(&con->waiting_requests); | ||
207 | if (test_and_set_bit(CF_READ_PENDING, &con->flags)) | ||
208 | return; | ||
209 | |||
210 | spin_lock_bh(&read_sockets_lock); | ||
211 | list_add_tail(&con->read_list, &read_sockets); | ||
212 | spin_unlock_bh(&read_sockets_lock); | ||
213 | |||
214 | wake_up_interruptible(&lowcomms_recv_waitq); | ||
215 | } | ||
216 | |||
217 | static void lowcomms_write_space(struct sock *sk) | ||
218 | { | ||
219 | struct connection *con = sock2con(sk); | ||
220 | |||
221 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags)) | ||
222 | return; | ||
223 | |||
224 | spin_lock_bh(&write_sockets_lock); | ||
225 | list_add_tail(&con->write_list, &write_sockets); | ||
226 | spin_unlock_bh(&write_sockets_lock); | ||
227 | |||
228 | wake_up_interruptible(&lowcomms_send_waitq); | ||
229 | } | ||
230 | |||
231 | static inline void lowcomms_connect_sock(struct connection *con) | ||
232 | { | ||
233 | if (test_and_set_bit(CF_CONNECT_PENDING, &con->flags)) | ||
234 | return; | ||
235 | |||
236 | spin_lock_bh(&state_sockets_lock); | ||
237 | list_add_tail(&con->state_list, &state_sockets); | ||
238 | spin_unlock_bh(&state_sockets_lock); | ||
239 | |||
240 | wake_up_interruptible(&lowcomms_send_waitq); | ||
241 | } | ||
242 | |||
243 | static void lowcomms_state_change(struct sock *sk) | ||
244 | { | ||
245 | if (sk->sk_state == TCP_ESTABLISHED) | ||
246 | lowcomms_write_space(sk); | ||
247 | } | ||
248 | |||
249 | /* Make a socket active */ | ||
250 | static int add_sock(struct socket *sock, struct connection *con) | ||
251 | { | ||
252 | con->sock = sock; | ||
253 | |||
254 | /* Install a data_ready callback */ | ||
255 | con->sock->sk->sk_data_ready = lowcomms_data_ready; | ||
256 | con->sock->sk->sk_write_space = lowcomms_write_space; | ||
257 | con->sock->sk->sk_state_change = lowcomms_state_change; | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* Add the port number to an IP6 or 4 sockaddr and return the address | ||
263 | length */ | ||
264 | static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | ||
265 | int *addr_len) | ||
266 | { | ||
267 | saddr->ss_family = dlm_local_addr.ss_family; | ||
268 | if (saddr->ss_family == AF_INET) { | ||
269 | struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr; | ||
270 | in4_addr->sin_port = cpu_to_be16(port); | ||
271 | *addr_len = sizeof(struct sockaddr_in); | ||
272 | } else { | ||
273 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | ||
274 | in6_addr->sin6_port = cpu_to_be16(port); | ||
275 | *addr_len = sizeof(struct sockaddr_in6); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* Close a remote connection and tidy up */ | ||
280 | static void close_connection(struct connection *con, bool and_other) | ||
281 | { | ||
282 | down_write(&con->sock_sem); | ||
283 | |||
284 | if (con->sock) { | ||
285 | sock_release(con->sock); | ||
286 | con->sock = NULL; | ||
287 | } | ||
288 | if (con->othercon && and_other) { | ||
289 | /* Will only re-enter once. */ | ||
290 | close_connection(con->othercon, false); | ||
291 | } | ||
292 | if (con->rx_page) { | ||
293 | __free_page(con->rx_page); | ||
294 | con->rx_page = NULL; | ||
295 | } | ||
296 | con->retries = 0; | ||
297 | up_write(&con->sock_sem); | ||
298 | } | ||
299 | |||
300 | /* Data received from remote end */ | ||
301 | static int receive_from_sock(struct connection *con) | ||
302 | { | ||
303 | int ret = 0; | ||
304 | struct msghdr msg; | ||
305 | struct iovec iov[2]; | ||
306 | mm_segment_t fs; | ||
307 | unsigned len; | ||
308 | int r; | ||
309 | int call_again_soon = 0; | ||
310 | |||
311 | down_read(&con->sock_sem); | ||
312 | |||
313 | if (con->sock == NULL) | ||
314 | goto out; | ||
315 | if (con->rx_page == NULL) { | ||
316 | /* | ||
317 | * This doesn't need to be atomic, but I think it should | ||
318 | * improve performance if it is. | ||
319 | */ | ||
320 | con->rx_page = alloc_page(GFP_ATOMIC); | ||
321 | if (con->rx_page == NULL) | ||
322 | goto out_resched; | ||
323 | cbuf_init(&con->cb, PAGE_CACHE_SIZE); | ||
324 | } | ||
325 | |||
326 | msg.msg_control = NULL; | ||
327 | msg.msg_controllen = 0; | ||
328 | msg.msg_iovlen = 1; | ||
329 | msg.msg_iov = iov; | ||
330 | msg.msg_name = NULL; | ||
331 | msg.msg_namelen = 0; | ||
332 | msg.msg_flags = 0; | ||
333 | |||
334 | /* | ||
335 | * iov[0] is the bit of the circular buffer between the current end | ||
336 | * point (cb.base + cb.len) and the end of the buffer. | ||
337 | */ | ||
338 | iov[0].iov_len = con->cb.base - cbuf_data(&con->cb); | ||
339 | iov[0].iov_base = page_address(con->rx_page) + cbuf_data(&con->cb); | ||
340 | iov[1].iov_len = 0; | ||
341 | |||
342 | /* | ||
343 | * iov[1] is the bit of the circular buffer between the start of the | ||
344 | * buffer and the start of the currently used section (cb.base) | ||
345 | */ | ||
346 | if (cbuf_data(&con->cb) >= con->cb.base) { | ||
347 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&con->cb); | ||
348 | iov[1].iov_len = con->cb.base; | ||
349 | iov[1].iov_base = page_address(con->rx_page); | ||
350 | msg.msg_iovlen = 2; | ||
351 | } | ||
352 | len = iov[0].iov_len + iov[1].iov_len; | ||
353 | |||
354 | fs = get_fs(); | ||
355 | set_fs(get_ds()); | ||
356 | r = ret = sock_recvmsg(con->sock, &msg, len, | ||
357 | MSG_DONTWAIT | MSG_NOSIGNAL); | ||
358 | set_fs(fs); | ||
359 | |||
360 | if (ret <= 0) | ||
361 | goto out_close; | ||
362 | if (ret == len) | ||
363 | call_again_soon = 1; | ||
364 | cbuf_add(&con->cb, ret); | ||
365 | ret = dlm_process_incoming_buffer(con->nodeid, | ||
366 | page_address(con->rx_page), | ||
367 | con->cb.base, con->cb.len, | ||
368 | PAGE_CACHE_SIZE); | ||
369 | if (ret == -EBADMSG) { | ||
370 | printk(KERN_INFO "dlm: lowcomms: addr=%p, base=%u, len=%u, " | ||
371 | "iov_len=%u, iov_base[0]=%p, read=%d\n", | ||
372 | page_address(con->rx_page), con->cb.base, con->cb.len, | ||
373 | len, iov[0].iov_base, r); | ||
374 | } | ||
375 | if (ret < 0) | ||
376 | goto out_close; | ||
377 | cbuf_eat(&con->cb, ret); | ||
378 | |||
379 | if (cbuf_empty(&con->cb) && !call_again_soon) { | ||
380 | __free_page(con->rx_page); | ||
381 | con->rx_page = NULL; | ||
382 | } | ||
383 | |||
384 | out: | ||
385 | if (call_again_soon) | ||
386 | goto out_resched; | ||
387 | up_read(&con->sock_sem); | ||
388 | return 0; | ||
389 | |||
390 | out_resched: | ||
391 | lowcomms_data_ready(con->sock->sk, 0); | ||
392 | up_read(&con->sock_sem); | ||
393 | cond_resched(); | ||
394 | return 0; | ||
395 | |||
396 | out_close: | ||
397 | up_read(&con->sock_sem); | ||
398 | if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { | ||
399 | close_connection(con, false); | ||
400 | /* Reconnect when there is something to send */ | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | /* Listening socket is busy, accept a connection */ | ||
407 | static int accept_from_sock(struct connection *con) | ||
408 | { | ||
409 | int result; | ||
410 | struct sockaddr_storage peeraddr; | ||
411 | struct socket *newsock; | ||
412 | int len; | ||
413 | int nodeid; | ||
414 | struct connection *newcon; | ||
415 | |||
416 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
417 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
418 | IPPROTO_TCP, &newsock); | ||
419 | if (result < 0) | ||
420 | return -ENOMEM; | ||
421 | |||
422 | down_read(&con->sock_sem); | ||
423 | |||
424 | result = -ENOTCONN; | ||
425 | if (con->sock == NULL) | ||
426 | goto accept_err; | ||
427 | |||
428 | newsock->type = con->sock->type; | ||
429 | newsock->ops = con->sock->ops; | ||
430 | |||
431 | result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK); | ||
432 | if (result < 0) | ||
433 | goto accept_err; | ||
434 | |||
435 | /* Get the connected socket's peer */ | ||
436 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
437 | if (newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, | ||
438 | &len, 2)) { | ||
439 | result = -ECONNABORTED; | ||
440 | goto accept_err; | ||
441 | } | ||
442 | |||
443 | /* Get the new node's NODEID */ | ||
444 | make_sockaddr(&peeraddr, 0, &len); | ||
445 | if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) { | ||
446 | printk("dlm: connect from non cluster node\n"); | ||
447 | sock_release(newsock); | ||
448 | up_read(&con->sock_sem); | ||
449 | return -1; | ||
450 | } | ||
451 | |||
452 | log_print("got connection from %d", nodeid); | ||
453 | |||
454 | /* Check to see if we already have a connection to this node. This | ||
455 | * could happen if the two nodes initiate a connection at roughly | ||
456 | * the same time and the connections cross on the wire. | ||
457 | * TEMPORARY FIX: | ||
458 | * In this case we store the incoming one in "othercon" | ||
459 | */ | ||
460 | newcon = nodeid2con(nodeid, GFP_KERNEL); | ||
461 | if (!newcon) { | ||
462 | result = -ENOMEM; | ||
463 | goto accept_err; | ||
464 | } | ||
465 | down_write(&newcon->sock_sem); | ||
466 | if (newcon->sock) { | ||
467 | struct connection *othercon = newcon->othercon; | ||
468 | |||
469 | if (!othercon) { | ||
470 | othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL); | ||
471 | if (!othercon) { | ||
472 | printk("dlm: failed to allocate incoming socket\n"); | ||
473 | up_write(&newcon->sock_sem); | ||
474 | result = -ENOMEM; | ||
475 | goto accept_err; | ||
476 | } | ||
477 | othercon->nodeid = nodeid; | ||
478 | othercon->rx_action = receive_from_sock; | ||
479 | init_rwsem(&othercon->sock_sem); | ||
480 | set_bit(CF_IS_OTHERCON, &othercon->flags); | ||
481 | newcon->othercon = othercon; | ||
482 | } | ||
483 | othercon->sock = newsock; | ||
484 | newsock->sk->sk_user_data = othercon; | ||
485 | add_sock(newsock, othercon); | ||
486 | } | ||
487 | else { | ||
488 | newsock->sk->sk_user_data = newcon; | ||
489 | newcon->rx_action = receive_from_sock; | ||
490 | add_sock(newsock, newcon); | ||
491 | |||
492 | } | ||
493 | |||
494 | up_write(&newcon->sock_sem); | ||
495 | |||
496 | /* | ||
497 | * Add it to the active queue in case we got data | ||
498 | * beween processing the accept adding the socket | ||
499 | * to the read_sockets list | ||
500 | */ | ||
501 | lowcomms_data_ready(newsock->sk, 0); | ||
502 | up_read(&con->sock_sem); | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | accept_err: | ||
507 | up_read(&con->sock_sem); | ||
508 | sock_release(newsock); | ||
509 | |||
510 | if (result != -EAGAIN) | ||
511 | printk("dlm: error accepting connection from node: %d\n", result); | ||
512 | return result; | ||
513 | } | ||
514 | |||
515 | /* Connect a new socket to its peer */ | ||
516 | static void connect_to_sock(struct connection *con) | ||
517 | { | ||
518 | int result = -EHOSTUNREACH; | ||
519 | struct sockaddr_storage saddr; | ||
520 | int addr_len; | ||
521 | struct socket *sock; | ||
522 | |||
523 | if (con->nodeid == 0) { | ||
524 | log_print("attempt to connect sock 0 foiled"); | ||
525 | return; | ||
526 | } | ||
527 | |||
528 | down_write(&con->sock_sem); | ||
529 | if (con->retries++ > MAX_CONNECT_RETRIES) | ||
530 | goto out; | ||
531 | |||
532 | /* Some odd races can cause double-connects, ignore them */ | ||
533 | if (con->sock) { | ||
534 | result = 0; | ||
535 | goto out; | ||
536 | } | ||
537 | |||
538 | /* Create a socket to communicate with */ | ||
539 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
540 | IPPROTO_TCP, &sock); | ||
541 | if (result < 0) | ||
542 | goto out_err; | ||
543 | |||
544 | memset(&saddr, 0, sizeof(saddr)); | ||
545 | if (dlm_nodeid_to_addr(con->nodeid, &saddr)) | ||
546 | goto out_err; | ||
547 | |||
548 | sock->sk->sk_user_data = con; | ||
549 | con->rx_action = receive_from_sock; | ||
550 | |||
551 | make_sockaddr(&saddr, dlm_config.tcp_port, &addr_len); | ||
552 | |||
553 | add_sock(sock, con); | ||
554 | |||
555 | log_print("connecting to %d", con->nodeid); | ||
556 | result = | ||
557 | sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, | ||
558 | O_NONBLOCK); | ||
559 | if (result == -EINPROGRESS) | ||
560 | result = 0; | ||
561 | if (result == 0) | ||
562 | goto out; | ||
563 | |||
564 | out_err: | ||
565 | if (con->sock) { | ||
566 | sock_release(con->sock); | ||
567 | con->sock = NULL; | ||
568 | } | ||
569 | /* | ||
570 | * Some errors are fatal and this list might need adjusting. For other | ||
571 | * errors we try again until the max number of retries is reached. | ||
572 | */ | ||
573 | if (result != -EHOSTUNREACH && result != -ENETUNREACH && | ||
574 | result != -ENETDOWN && result != EINVAL | ||
575 | && result != -EPROTONOSUPPORT) { | ||
576 | lowcomms_connect_sock(con); | ||
577 | result = 0; | ||
578 | } | ||
579 | out: | ||
580 | up_write(&con->sock_sem); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | static struct socket *create_listen_sock(struct connection *con, | ||
585 | struct sockaddr_storage *saddr) | ||
586 | { | ||
587 | struct socket *sock = NULL; | ||
588 | mm_segment_t fs; | ||
589 | int result = 0; | ||
590 | int one = 1; | ||
591 | int addr_len; | ||
592 | |||
593 | if (dlm_local_addr.ss_family == AF_INET) | ||
594 | addr_len = sizeof(struct sockaddr_in); | ||
595 | else | ||
596 | addr_len = sizeof(struct sockaddr_in6); | ||
597 | |||
598 | /* Create a socket to communicate with */ | ||
599 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
600 | if (result < 0) { | ||
601 | printk("dlm: Can't create listening comms socket\n"); | ||
602 | goto create_out; | ||
603 | } | ||
604 | |||
605 | fs = get_fs(); | ||
606 | set_fs(get_ds()); | ||
607 | result = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, | ||
608 | (char *)&one, sizeof(one)); | ||
609 | set_fs(fs); | ||
610 | if (result < 0) { | ||
611 | printk("dlm: Failed to set SO_REUSEADDR on socket: result=%d\n", | ||
612 | result); | ||
613 | } | ||
614 | sock->sk->sk_user_data = con; | ||
615 | con->rx_action = accept_from_sock; | ||
616 | con->sock = sock; | ||
617 | |||
618 | /* Bind to our port */ | ||
619 | make_sockaddr(saddr, dlm_config.tcp_port, &addr_len); | ||
620 | result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len); | ||
621 | if (result < 0) { | ||
622 | printk("dlm: Can't bind to port %d\n", dlm_config.tcp_port); | ||
623 | sock_release(sock); | ||
624 | sock = NULL; | ||
625 | con->sock = NULL; | ||
626 | goto create_out; | ||
627 | } | ||
628 | |||
629 | fs = get_fs(); | ||
630 | set_fs(get_ds()); | ||
631 | |||
632 | result = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, | ||
633 | (char *)&one, sizeof(one)); | ||
634 | set_fs(fs); | ||
635 | if (result < 0) { | ||
636 | printk("dlm: Set keepalive failed: %d\n", result); | ||
637 | } | ||
638 | |||
639 | result = sock->ops->listen(sock, 5); | ||
640 | if (result < 0) { | ||
641 | printk("dlm: Can't listen on port %d\n", dlm_config.tcp_port); | ||
642 | sock_release(sock); | ||
643 | sock = NULL; | ||
644 | goto create_out; | ||
645 | } | ||
646 | |||
647 | create_out: | ||
648 | return sock; | ||
649 | } | ||
650 | |||
651 | |||
652 | /* Listen on all interfaces */ | ||
653 | static int listen_for_all(void) | ||
654 | { | ||
655 | struct socket *sock = NULL; | ||
656 | struct connection *con = nodeid2con(0, GFP_KERNEL); | ||
657 | int result = -EINVAL; | ||
658 | |||
659 | /* We don't support multi-homed hosts */ | ||
660 | set_bit(CF_IS_OTHERCON, &con->flags); | ||
661 | |||
662 | sock = create_listen_sock(con, &dlm_local_addr); | ||
663 | if (sock) { | ||
664 | add_sock(sock, con); | ||
665 | result = 0; | ||
666 | } | ||
667 | else { | ||
668 | result = -EADDRINUSE; | ||
669 | } | ||
670 | |||
671 | return result; | ||
672 | } | ||
673 | |||
674 | |||
675 | |||
676 | static struct writequeue_entry *new_writequeue_entry(struct connection *con, | ||
677 | gfp_t allocation) | ||
678 | { | ||
679 | struct writequeue_entry *entry; | ||
680 | |||
681 | entry = kmalloc(sizeof(struct writequeue_entry), allocation); | ||
682 | if (!entry) | ||
683 | return NULL; | ||
684 | |||
685 | entry->page = alloc_page(allocation); | ||
686 | if (!entry->page) { | ||
687 | kfree(entry); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | entry->offset = 0; | ||
692 | entry->len = 0; | ||
693 | entry->end = 0; | ||
694 | entry->users = 0; | ||
695 | entry->con = con; | ||
696 | |||
697 | return entry; | ||
698 | } | ||
699 | |||
700 | void *dlm_lowcomms_get_buffer(int nodeid, int len, | ||
701 | gfp_t allocation, char **ppc) | ||
702 | { | ||
703 | struct connection *con; | ||
704 | struct writequeue_entry *e; | ||
705 | int offset = 0; | ||
706 | int users = 0; | ||
707 | |||
708 | con = nodeid2con(nodeid, allocation); | ||
709 | if (!con) | ||
710 | return NULL; | ||
711 | |||
712 | e = list_entry(con->writequeue.prev, struct writequeue_entry, list); | ||
713 | if ((&e->list == &con->writequeue) || | ||
714 | (PAGE_CACHE_SIZE - e->end < len)) { | ||
715 | e = NULL; | ||
716 | } else { | ||
717 | offset = e->end; | ||
718 | e->end += len; | ||
719 | users = e->users++; | ||
720 | } | ||
721 | spin_unlock(&con->writequeue_lock); | ||
722 | |||
723 | if (e) { | ||
724 | got_one: | ||
725 | if (users == 0) | ||
726 | kmap(e->page); | ||
727 | *ppc = page_address(e->page) + offset; | ||
728 | return e; | ||
729 | } | ||
730 | |||
731 | e = new_writequeue_entry(con, allocation); | ||
732 | if (e) { | ||
733 | spin_lock(&con->writequeue_lock); | ||
734 | offset = e->end; | ||
735 | e->end += len; | ||
736 | users = e->users++; | ||
737 | list_add_tail(&e->list, &con->writequeue); | ||
738 | spin_unlock(&con->writequeue_lock); | ||
739 | goto got_one; | ||
740 | } | ||
741 | return NULL; | ||
742 | } | ||
743 | |||
744 | void dlm_lowcomms_commit_buffer(void *mh) | ||
745 | { | ||
746 | struct writequeue_entry *e = (struct writequeue_entry *)mh; | ||
747 | struct connection *con = e->con; | ||
748 | int users; | ||
749 | |||
750 | users = --e->users; | ||
751 | if (users) | ||
752 | goto out; | ||
753 | e->len = e->end - e->offset; | ||
754 | kunmap(e->page); | ||
755 | spin_unlock(&con->writequeue_lock); | ||
756 | |||
757 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags) == 0) { | ||
758 | spin_lock_bh(&write_sockets_lock); | ||
759 | list_add_tail(&con->write_list, &write_sockets); | ||
760 | spin_unlock_bh(&write_sockets_lock); | ||
761 | |||
762 | wake_up_interruptible(&lowcomms_send_waitq); | ||
763 | } | ||
764 | return; | ||
765 | |||
766 | out: | ||
767 | spin_unlock(&con->writequeue_lock); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | static void free_entry(struct writequeue_entry *e) | ||
772 | { | ||
773 | __free_page(e->page); | ||
774 | kfree(e); | ||
775 | } | ||
776 | |||
777 | /* Send a message */ | ||
778 | static void send_to_sock(struct connection *con) | ||
779 | { | ||
780 | int ret = 0; | ||
781 | ssize_t(*sendpage) (struct socket *, struct page *, int, size_t, int); | ||
782 | const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; | ||
783 | struct writequeue_entry *e; | ||
784 | int len, offset; | ||
785 | |||
786 | down_read(&con->sock_sem); | ||
787 | if (con->sock == NULL) | ||
788 | goto out_connect; | ||
789 | |||
790 | sendpage = con->sock->ops->sendpage; | ||
791 | |||
792 | spin_lock(&con->writequeue_lock); | ||
793 | for (;;) { | ||
794 | e = list_entry(con->writequeue.next, struct writequeue_entry, | ||
795 | list); | ||
796 | if ((struct list_head *) e == &con->writequeue) | ||
797 | break; | ||
798 | |||
799 | len = e->len; | ||
800 | offset = e->offset; | ||
801 | BUG_ON(len == 0 && e->users == 0); | ||
802 | spin_unlock(&con->writequeue_lock); | ||
803 | |||
804 | ret = 0; | ||
805 | if (len) { | ||
806 | ret = sendpage(con->sock, e->page, offset, len, | ||
807 | msg_flags); | ||
808 | if (ret == -EAGAIN || ret == 0) | ||
809 | goto out; | ||
810 | if (ret <= 0) | ||
811 | goto send_error; | ||
812 | } | ||
813 | else { | ||
814 | /* Don't starve people filling buffers */ | ||
815 | cond_resched(); | ||
816 | } | ||
817 | |||
818 | spin_lock(&con->writequeue_lock); | ||
819 | e->offset += ret; | ||
820 | e->len -= ret; | ||
821 | |||
822 | if (e->len == 0 && e->users == 0) { | ||
823 | list_del(&e->list); | ||
824 | kunmap(e->page); | ||
825 | free_entry(e); | ||
826 | continue; | ||
827 | } | ||
828 | } | ||
829 | spin_unlock(&con->writequeue_lock); | ||
830 | out: | ||
831 | up_read(&con->sock_sem); | ||
832 | return; | ||
833 | |||
834 | send_error: | ||
835 | up_read(&con->sock_sem); | ||
836 | close_connection(con, false); | ||
837 | lowcomms_connect_sock(con); | ||
838 | return; | ||
839 | |||
840 | out_connect: | ||
841 | up_read(&con->sock_sem); | ||
842 | lowcomms_connect_sock(con); | ||
843 | return; | ||
844 | } | ||
845 | |||
846 | static void clean_one_writequeue(struct connection *con) | ||
847 | { | ||
848 | struct list_head *list; | ||
849 | struct list_head *temp; | ||
850 | |||
851 | spin_lock(&con->writequeue_lock); | ||
852 | list_for_each_safe(list, temp, &con->writequeue) { | ||
853 | struct writequeue_entry *e = | ||
854 | list_entry(list, struct writequeue_entry, list); | ||
855 | list_del(&e->list); | ||
856 | free_entry(e); | ||
857 | } | ||
858 | spin_unlock(&con->writequeue_lock); | ||
859 | } | ||
860 | |||
861 | /* Called from recovery when it knows that a node has | ||
862 | left the cluster */ | ||
863 | int dlm_lowcomms_close(int nodeid) | ||
864 | { | ||
865 | struct connection *con; | ||
866 | |||
867 | if (!connections) | ||
868 | goto out; | ||
869 | |||
870 | log_print("closing connection to node %d", nodeid); | ||
871 | con = nodeid2con(nodeid, 0); | ||
872 | if (con) { | ||
873 | clean_one_writequeue(con); | ||
874 | close_connection(con, true); | ||
875 | atomic_set(&con->waiting_requests, 0); | ||
876 | } | ||
877 | return 0; | ||
878 | |||
879 | out: | ||
880 | return -1; | ||
881 | } | ||
882 | |||
883 | /* API send message call, may queue the request */ | ||
884 | /* N.B. This is the old interface - use the new one for new calls */ | ||
885 | int lowcomms_send_message(int nodeid, char *buf, int len, gfp_t allocation) | ||
886 | { | ||
887 | struct writequeue_entry *e; | ||
888 | char *b; | ||
889 | |||
890 | e = dlm_lowcomms_get_buffer(nodeid, len, allocation, &b); | ||
891 | if (e) { | ||
892 | memcpy(b, buf, len); | ||
893 | dlm_lowcomms_commit_buffer(e); | ||
894 | return 0; | ||
895 | } | ||
896 | return -ENOBUFS; | ||
897 | } | ||
898 | |||
899 | /* Look for activity on active sockets */ | ||
900 | static void process_sockets(void) | ||
901 | { | ||
902 | struct list_head *list; | ||
903 | struct list_head *temp; | ||
904 | int count = 0; | ||
905 | |||
906 | spin_lock_bh(&read_sockets_lock); | ||
907 | list_for_each_safe(list, temp, &read_sockets) { | ||
908 | |||
909 | struct connection *con = | ||
910 | list_entry(list, struct connection, read_list); | ||
911 | list_del(&con->read_list); | ||
912 | clear_bit(CF_READ_PENDING, &con->flags); | ||
913 | |||
914 | spin_unlock_bh(&read_sockets_lock); | ||
915 | |||
916 | /* This can reach zero if we are processing requests | ||
917 | * as they come in. | ||
918 | */ | ||
919 | if (atomic_read(&con->waiting_requests) == 0) { | ||
920 | spin_lock_bh(&read_sockets_lock); | ||
921 | continue; | ||
922 | } | ||
923 | |||
924 | do { | ||
925 | con->rx_action(con); | ||
926 | |||
927 | /* Don't starve out everyone else */ | ||
928 | if (++count >= MAX_RX_MSG_COUNT) { | ||
929 | cond_resched(); | ||
930 | count = 0; | ||
931 | } | ||
932 | |||
933 | } while (!atomic_dec_and_test(&con->waiting_requests) && | ||
934 | !kthread_should_stop()); | ||
935 | |||
936 | spin_lock_bh(&read_sockets_lock); | ||
937 | } | ||
938 | spin_unlock_bh(&read_sockets_lock); | ||
939 | } | ||
940 | |||
941 | /* Try to send any messages that are pending | ||
942 | */ | ||
943 | static void process_output_queue(void) | ||
944 | { | ||
945 | struct list_head *list; | ||
946 | struct list_head *temp; | ||
947 | |||
948 | spin_lock_bh(&write_sockets_lock); | ||
949 | list_for_each_safe(list, temp, &write_sockets) { | ||
950 | struct connection *con = | ||
951 | list_entry(list, struct connection, write_list); | ||
952 | clear_bit(CF_WRITE_PENDING, &con->flags); | ||
953 | list_del(&con->write_list); | ||
954 | |||
955 | spin_unlock_bh(&write_sockets_lock); | ||
956 | send_to_sock(con); | ||
957 | spin_lock_bh(&write_sockets_lock); | ||
958 | } | ||
959 | spin_unlock_bh(&write_sockets_lock); | ||
960 | } | ||
961 | |||
962 | static void process_state_queue(void) | ||
963 | { | ||
964 | struct list_head *list; | ||
965 | struct list_head *temp; | ||
966 | |||
967 | spin_lock_bh(&state_sockets_lock); | ||
968 | list_for_each_safe(list, temp, &state_sockets) { | ||
969 | struct connection *con = | ||
970 | list_entry(list, struct connection, state_list); | ||
971 | list_del(&con->state_list); | ||
972 | clear_bit(CF_CONNECT_PENDING, &con->flags); | ||
973 | spin_unlock_bh(&state_sockets_lock); | ||
974 | |||
975 | connect_to_sock(con); | ||
976 | spin_lock_bh(&state_sockets_lock); | ||
977 | } | ||
978 | spin_unlock_bh(&state_sockets_lock); | ||
979 | } | ||
980 | |||
981 | |||
982 | /* Discard all entries on the write queues */ | ||
983 | static void clean_writequeues(void) | ||
984 | { | ||
985 | int nodeid; | ||
986 | |||
987 | for (nodeid = 1; nodeid < conn_array_size; nodeid++) { | ||
988 | struct connection *con = nodeid2con(nodeid, 0); | ||
989 | |||
990 | if (con) | ||
991 | clean_one_writequeue(con); | ||
992 | } | ||
993 | } | ||
994 | |||
995 | static int read_list_empty(void) | ||
996 | { | ||
997 | int status; | ||
998 | |||
999 | spin_lock_bh(&read_sockets_lock); | ||
1000 | status = list_empty(&read_sockets); | ||
1001 | spin_unlock_bh(&read_sockets_lock); | ||
1002 | |||
1003 | return status; | ||
1004 | } | ||
1005 | |||
1006 | /* DLM Transport comms receive daemon */ | ||
1007 | static int dlm_recvd(void *data) | ||
1008 | { | ||
1009 | init_waitqueue_entry(&lowcomms_recv_waitq_head, current); | ||
1010 | add_wait_queue(&lowcomms_recv_waitq, &lowcomms_recv_waitq_head); | ||
1011 | |||
1012 | while (!kthread_should_stop()) { | ||
1013 | set_current_state(TASK_INTERRUPTIBLE); | ||
1014 | if (read_list_empty()) | ||
1015 | cond_resched(); | ||
1016 | set_current_state(TASK_RUNNING); | ||
1017 | |||
1018 | process_sockets(); | ||
1019 | } | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static int write_and_state_lists_empty(void) | ||
1025 | { | ||
1026 | int status; | ||
1027 | |||
1028 | spin_lock_bh(&write_sockets_lock); | ||
1029 | status = list_empty(&write_sockets); | ||
1030 | spin_unlock_bh(&write_sockets_lock); | ||
1031 | |||
1032 | spin_lock_bh(&state_sockets_lock); | ||
1033 | if (list_empty(&state_sockets) == 0) | ||
1034 | status = 0; | ||
1035 | spin_unlock_bh(&state_sockets_lock); | ||
1036 | |||
1037 | return status; | ||
1038 | } | ||
1039 | |||
1040 | /* DLM Transport send daemon */ | ||
1041 | static int dlm_sendd(void *data) | ||
1042 | { | ||
1043 | init_waitqueue_entry(&lowcomms_send_waitq_head, current); | ||
1044 | add_wait_queue(&lowcomms_send_waitq, &lowcomms_send_waitq_head); | ||
1045 | |||
1046 | while (!kthread_should_stop()) { | ||
1047 | set_current_state(TASK_INTERRUPTIBLE); | ||
1048 | if (write_and_state_lists_empty()) | ||
1049 | cond_resched(); | ||
1050 | set_current_state(TASK_RUNNING); | ||
1051 | |||
1052 | process_state_queue(); | ||
1053 | process_output_queue(); | ||
1054 | } | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static void daemons_stop(void) | ||
1060 | { | ||
1061 | kthread_stop(recv_task); | ||
1062 | kthread_stop(send_task); | ||
1063 | } | ||
1064 | |||
1065 | static int daemons_start(void) | ||
1066 | { | ||
1067 | struct task_struct *p; | ||
1068 | int error; | ||
1069 | |||
1070 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | ||
1071 | error = IS_ERR(p); | ||
1072 | if (error) { | ||
1073 | log_print("can't start dlm_recvd %d", error); | ||
1074 | return error; | ||
1075 | } | ||
1076 | recv_task = p; | ||
1077 | |||
1078 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | ||
1079 | error = IS_ERR(p); | ||
1080 | if (error) { | ||
1081 | log_print("can't start dlm_sendd %d", error); | ||
1082 | kthread_stop(recv_task); | ||
1083 | return error; | ||
1084 | } | ||
1085 | send_task = p; | ||
1086 | |||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | /* | ||
1091 | * Return the largest buffer size we can cope with. | ||
1092 | */ | ||
1093 | int lowcomms_max_buffer_size(void) | ||
1094 | { | ||
1095 | return PAGE_CACHE_SIZE; | ||
1096 | } | ||
1097 | |||
1098 | void dlm_lowcomms_stop(void) | ||
1099 | { | ||
1100 | int i; | ||
1101 | |||
1102 | /* Set all the flags to prevent any | ||
1103 | socket activity. | ||
1104 | */ | ||
1105 | for (i = 0; i < conn_array_size; i++) { | ||
1106 | if (connections[i]) | ||
1107 | connections[i]->flags |= 0xFF; | ||
1108 | } | ||
1109 | |||
1110 | daemons_stop(); | ||
1111 | clean_writequeues(); | ||
1112 | |||
1113 | for (i = 0; i < conn_array_size; i++) { | ||
1114 | if (connections[i]) { | ||
1115 | close_connection(connections[i], true); | ||
1116 | if (connections[i]->othercon) | ||
1117 | kmem_cache_free(con_cache, connections[i]->othercon); | ||
1118 | kmem_cache_free(con_cache, connections[i]); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | kfree(connections); | ||
1123 | connections = NULL; | ||
1124 | |||
1125 | kmem_cache_destroy(con_cache); | ||
1126 | } | ||
1127 | |||
1128 | /* This is quite likely to sleep... */ | ||
1129 | int dlm_lowcomms_start(void) | ||
1130 | { | ||
1131 | int error = 0; | ||
1132 | |||
1133 | error = -ENOMEM; | ||
1134 | connections = kzalloc(sizeof(struct connection *) * | ||
1135 | NODE_INCREMENT, GFP_KERNEL); | ||
1136 | if (!connections) | ||
1137 | goto out; | ||
1138 | |||
1139 | conn_array_size = NODE_INCREMENT; | ||
1140 | |||
1141 | if (dlm_our_addr(&dlm_local_addr, 0)) { | ||
1142 | log_print("no local IP address has been set"); | ||
1143 | goto fail_free_conn; | ||
1144 | } | ||
1145 | if (!dlm_our_addr(&dlm_local_addr, 1)) { | ||
1146 | log_print("This dlm comms module does not support multi-homed clustering"); | ||
1147 | goto fail_free_conn; | ||
1148 | } | ||
1149 | |||
1150 | con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection), | ||
1151 | __alignof__(struct connection), 0, | ||
1152 | NULL, NULL); | ||
1153 | if (!con_cache) | ||
1154 | goto fail_free_conn; | ||
1155 | |||
1156 | |||
1157 | /* Start listening */ | ||
1158 | error = listen_for_all(); | ||
1159 | if (error) | ||
1160 | goto fail_unlisten; | ||
1161 | |||
1162 | error = daemons_start(); | ||
1163 | if (error) | ||
1164 | goto fail_unlisten; | ||
1165 | |||
1166 | return 0; | ||
1167 | |||
1168 | fail_unlisten: | ||
1169 | close_connection(connections[0], false); | ||
1170 | kmem_cache_free(con_cache, connections[0]); | ||
1171 | kmem_cache_destroy(con_cache); | ||
1172 | |||
1173 | fail_free_conn: | ||
1174 | kfree(connections); | ||
1175 | |||
1176 | out: | ||
1177 | return error; | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1182 | * Emacs will notice this stuff at the end of the file and automatically | ||
1183 | * adjust the settings for this buffer only. This must remain at the end | ||
1184 | * of the file. | ||
1185 | * --------------------------------------------------------------------------- | ||
1186 | * Local variables: | ||
1187 | * c-file-style: "linux" | ||
1188 | * End: | ||
1189 | */ | ||
diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h index 2d045e0daae1..a9a9618c0d3f 100644 --- a/fs/dlm/lowcomms.h +++ b/fs/dlm/lowcomms.h | |||
@@ -14,8 +14,6 @@ | |||
14 | #ifndef __LOWCOMMS_DOT_H__ | 14 | #ifndef __LOWCOMMS_DOT_H__ |
15 | #define __LOWCOMMS_DOT_H__ | 15 | #define __LOWCOMMS_DOT_H__ |
16 | 16 | ||
17 | int dlm_lowcomms_init(void); | ||
18 | void dlm_lowcomms_exit(void); | ||
19 | int dlm_lowcomms_start(void); | 17 | int dlm_lowcomms_start(void); |
20 | void dlm_lowcomms_stop(void); | 18 | void dlm_lowcomms_stop(void); |
21 | int dlm_lowcomms_close(int nodeid); | 19 | int dlm_lowcomms_close(int nodeid); |
diff --git a/fs/dlm/main.c b/fs/dlm/main.c index a8da8dc36b2e..162fbae58fe5 100644 --- a/fs/dlm/main.c +++ b/fs/dlm/main.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include "lock.h" | 16 | #include "lock.h" |
17 | #include "user.h" | 17 | #include "user.h" |
18 | #include "memory.h" | 18 | #include "memory.h" |
19 | #include "lowcomms.h" | ||
20 | #include "config.h" | 19 | #include "config.h" |
21 | 20 | ||
22 | #ifdef CONFIG_DLM_DEBUG | 21 | #ifdef CONFIG_DLM_DEBUG |
@@ -47,20 +46,14 @@ static int __init init_dlm(void) | |||
47 | if (error) | 46 | if (error) |
48 | goto out_config; | 47 | goto out_config; |
49 | 48 | ||
50 | error = dlm_lowcomms_init(); | ||
51 | if (error) | ||
52 | goto out_debug; | ||
53 | |||
54 | error = dlm_user_init(); | 49 | error = dlm_user_init(); |
55 | if (error) | 50 | if (error) |
56 | goto out_lowcomms; | 51 | goto out_debug; |
57 | 52 | ||
58 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); | 53 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); |
59 | 54 | ||
60 | return 0; | 55 | return 0; |
61 | 56 | ||
62 | out_lowcomms: | ||
63 | dlm_lowcomms_exit(); | ||
64 | out_debug: | 57 | out_debug: |
65 | dlm_unregister_debugfs(); | 58 | dlm_unregister_debugfs(); |
66 | out_config: | 59 | out_config: |
@@ -76,7 +69,6 @@ static int __init init_dlm(void) | |||
76 | static void __exit exit_dlm(void) | 69 | static void __exit exit_dlm(void) |
77 | { | 70 | { |
78 | dlm_user_exit(); | 71 | dlm_user_exit(); |
79 | dlm_lowcomms_exit(); | ||
80 | dlm_config_exit(); | 72 | dlm_config_exit(); |
81 | dlm_memory_exit(); | 73 | dlm_memory_exit(); |
82 | dlm_lockspace_exit(); | 74 | dlm_lockspace_exit(); |
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index a3f7de7f3a8f..85e2897bd740 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -186,6 +186,14 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
186 | struct dlm_member *memb, *safe; | 186 | struct dlm_member *memb, *safe; |
187 | int i, error, found, pos = 0, neg = 0, low = -1; | 187 | int i, error, found, pos = 0, neg = 0, low = -1; |
188 | 188 | ||
189 | /* previously removed members that we've not finished removing need to | ||
190 | count as a negative change so the "neg" recovery steps will happen */ | ||
191 | |||
192 | list_for_each_entry(memb, &ls->ls_nodes_gone, list) { | ||
193 | log_debug(ls, "prev removed member %d", memb->nodeid); | ||
194 | neg++; | ||
195 | } | ||
196 | |||
189 | /* move departed members from ls_nodes to ls_nodes_gone */ | 197 | /* move departed members from ls_nodes to ls_nodes_gone */ |
190 | 198 | ||
191 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { | 199 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { |
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c index 989b608fd836..5352b03ff5aa 100644 --- a/fs/dlm/memory.c +++ b/fs/dlm/memory.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "config.h" | 15 | #include "config.h" |
16 | #include "memory.h" | 16 | #include "memory.h" |
17 | 17 | ||
18 | static kmem_cache_t *lkb_cache; | 18 | static struct kmem_cache *lkb_cache; |
19 | 19 | ||
20 | 20 | ||
21 | int dlm_memory_init(void) | 21 | int dlm_memory_init(void) |
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 518239a8b1e9..4cc31be9cd9d 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -90,13 +90,28 @@ static int check_config(struct dlm_ls *ls, struct rcom_config *rf, int nodeid) | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static void allow_sync_reply(struct dlm_ls *ls, uint64_t *new_seq) | ||
94 | { | ||
95 | spin_lock(&ls->ls_rcom_spin); | ||
96 | *new_seq = ++ls->ls_rcom_seq; | ||
97 | set_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
98 | spin_unlock(&ls->ls_rcom_spin); | ||
99 | } | ||
100 | |||
101 | static void disallow_sync_reply(struct dlm_ls *ls) | ||
102 | { | ||
103 | spin_lock(&ls->ls_rcom_spin); | ||
104 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
105 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | ||
106 | spin_unlock(&ls->ls_rcom_spin); | ||
107 | } | ||
108 | |||
93 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | 109 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) |
94 | { | 110 | { |
95 | struct dlm_rcom *rc; | 111 | struct dlm_rcom *rc; |
96 | struct dlm_mhandle *mh; | 112 | struct dlm_mhandle *mh; |
97 | int error = 0; | 113 | int error = 0; |
98 | 114 | ||
99 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
100 | ls->ls_recover_nodeid = nodeid; | 115 | ls->ls_recover_nodeid = nodeid; |
101 | 116 | ||
102 | if (nodeid == dlm_our_nodeid()) { | 117 | if (nodeid == dlm_our_nodeid()) { |
@@ -108,12 +123,14 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | |||
108 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); | 123 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); |
109 | if (error) | 124 | if (error) |
110 | goto out; | 125 | goto out; |
111 | rc->rc_id = ++ls->ls_rcom_seq; | 126 | |
127 | allow_sync_reply(ls, &rc->rc_id); | ||
128 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
112 | 129 | ||
113 | send_rcom(ls, mh, rc); | 130 | send_rcom(ls, mh, rc); |
114 | 131 | ||
115 | error = dlm_wait_function(ls, &rcom_response); | 132 | error = dlm_wait_function(ls, &rcom_response); |
116 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 133 | disallow_sync_reply(ls); |
117 | if (error) | 134 | if (error) |
118 | goto out; | 135 | goto out; |
119 | 136 | ||
@@ -150,14 +167,21 @@ static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
150 | 167 | ||
151 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 168 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
152 | { | 169 | { |
153 | if (rc_in->rc_id != ls->ls_rcom_seq) { | 170 | spin_lock(&ls->ls_rcom_spin); |
154 | log_debug(ls, "reject old reply %d got %llx wanted %llx", | 171 | if (!test_bit(LSFL_RCOM_WAIT, &ls->ls_flags) || |
155 | rc_in->rc_type, rc_in->rc_id, ls->ls_rcom_seq); | 172 | rc_in->rc_id != ls->ls_rcom_seq) { |
156 | return; | 173 | log_debug(ls, "reject reply %d from %d seq %llx expect %llx", |
174 | rc_in->rc_type, rc_in->rc_header.h_nodeid, | ||
175 | (unsigned long long)rc_in->rc_id, | ||
176 | (unsigned long long)ls->ls_rcom_seq); | ||
177 | goto out; | ||
157 | } | 178 | } |
158 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); | 179 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); |
159 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); | 180 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); |
181 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
160 | wake_up(&ls->ls_wait_general); | 182 | wake_up(&ls->ls_wait_general); |
183 | out: | ||
184 | spin_unlock(&ls->ls_rcom_spin); | ||
161 | } | 185 | } |
162 | 186 | ||
163 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 187 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
@@ -171,7 +195,6 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
171 | struct dlm_mhandle *mh; | 195 | struct dlm_mhandle *mh; |
172 | int error = 0, len = sizeof(struct dlm_rcom); | 196 | int error = 0, len = sizeof(struct dlm_rcom); |
173 | 197 | ||
174 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
175 | ls->ls_recover_nodeid = nodeid; | 198 | ls->ls_recover_nodeid = nodeid; |
176 | 199 | ||
177 | if (nodeid == dlm_our_nodeid()) { | 200 | if (nodeid == dlm_our_nodeid()) { |
@@ -185,12 +208,14 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
185 | if (error) | 208 | if (error) |
186 | goto out; | 209 | goto out; |
187 | memcpy(rc->rc_buf, last_name, last_len); | 210 | memcpy(rc->rc_buf, last_name, last_len); |
188 | rc->rc_id = ++ls->ls_rcom_seq; | 211 | |
212 | allow_sync_reply(ls, &rc->rc_id); | ||
213 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
189 | 214 | ||
190 | send_rcom(ls, mh, rc); | 215 | send_rcom(ls, mh, rc); |
191 | 216 | ||
192 | error = dlm_wait_function(ls, &rcom_response); | 217 | error = dlm_wait_function(ls, &rcom_response); |
193 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 218 | disallow_sync_reply(ls); |
194 | out: | 219 | out: |
195 | return error; | 220 | return error; |
196 | } | 221 | } |
@@ -370,9 +395,10 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
370 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | 395 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) |
371 | { | 396 | { |
372 | struct dlm_rcom *rc; | 397 | struct dlm_rcom *rc; |
398 | struct rcom_config *rf; | ||
373 | struct dlm_mhandle *mh; | 399 | struct dlm_mhandle *mh; |
374 | char *mb; | 400 | char *mb; |
375 | int mb_len = sizeof(struct dlm_rcom); | 401 | int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); |
376 | 402 | ||
377 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); | 403 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); |
378 | if (!mh) | 404 | if (!mh) |
@@ -391,6 +417,9 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | |||
391 | rc->rc_id = rc_in->rc_id; | 417 | rc->rc_id = rc_in->rc_id; |
392 | rc->rc_result = -ESRCH; | 418 | rc->rc_result = -ESRCH; |
393 | 419 | ||
420 | rf = (struct rcom_config *) rc->rc_buf; | ||
421 | rf->rf_lvblen = -1; | ||
422 | |||
394 | dlm_rcom_out(rc); | 423 | dlm_rcom_out(rc); |
395 | dlm_lowcomms_commit_buffer(mh); | 424 | dlm_lowcomms_commit_buffer(mh); |
396 | 425 | ||
@@ -412,9 +441,10 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid) | |||
412 | 441 | ||
413 | ls = dlm_find_lockspace_global(hd->h_lockspace); | 442 | ls = dlm_find_lockspace_global(hd->h_lockspace); |
414 | if (!ls) { | 443 | if (!ls) { |
415 | log_print("lockspace %x from %d not found", | 444 | log_print("lockspace %x from %d type %x not found", |
416 | hd->h_lockspace, nodeid); | 445 | hd->h_lockspace, nodeid, rc->rc_type); |
417 | send_ls_not_ready(nodeid, rc); | 446 | if (rc->rc_type == DLM_RCOM_STATUS) |
447 | send_ls_not_ready(nodeid, rc); | ||
418 | return; | 448 | return; |
419 | } | 449 | } |
420 | 450 | ||
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index a5e6d184872e..cf9f6831bab5 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -252,6 +252,7 @@ static void recover_list_clear(struct dlm_ls *ls) | |||
252 | spin_lock(&ls->ls_recover_list_lock); | 252 | spin_lock(&ls->ls_recover_list_lock); |
253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { | 253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { |
254 | list_del_init(&r->res_recover_list); | 254 | list_del_init(&r->res_recover_list); |
255 | r->res_recover_locks_count = 0; | ||
255 | dlm_put_rsb(r); | 256 | dlm_put_rsb(r); |
256 | ls->ls_recover_list_count--; | 257 | ls->ls_recover_list_count--; |
257 | } | 258 | } |
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 362e3eff4dc9..650536aa5139 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c | |||
@@ -45,7 +45,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
45 | unsigned long start; | 45 | unsigned long start; |
46 | int error, neg = 0; | 46 | int error, neg = 0; |
47 | 47 | ||
48 | log_debug(ls, "recover %llx", rv->seq); | 48 | log_debug(ls, "recover %llx", (unsigned long long)rv->seq); |
49 | 49 | ||
50 | mutex_lock(&ls->ls_recoverd_active); | 50 | mutex_lock(&ls->ls_recoverd_active); |
51 | 51 | ||
@@ -94,14 +94,6 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Purge directory-related requests that are saved in requestqueue. | ||
98 | * All dir requests from before recovery are invalid now due to the dir | ||
99 | * rebuild and will be resent by the requesting nodes. | ||
100 | */ | ||
101 | |||
102 | dlm_purge_requestqueue(ls); | ||
103 | |||
104 | /* | ||
105 | * Wait for all nodes to complete directory rebuild. | 97 | * Wait for all nodes to complete directory rebuild. |
106 | */ | 98 | */ |
107 | 99 | ||
@@ -164,10 +156,31 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
164 | */ | 156 | */ |
165 | 157 | ||
166 | dlm_recover_rsbs(ls); | 158 | dlm_recover_rsbs(ls); |
159 | } else { | ||
160 | /* | ||
161 | * Other lockspace members may be going through the "neg" steps | ||
162 | * while also adding us to the lockspace, in which case they'll | ||
163 | * be doing the recover_locks (RS_LOCKS) barrier. | ||
164 | */ | ||
165 | dlm_set_recover_status(ls, DLM_RS_LOCKS); | ||
166 | |||
167 | error = dlm_recover_locks_wait(ls); | ||
168 | if (error) { | ||
169 | log_error(ls, "recover_locks_wait failed %d", error); | ||
170 | goto fail; | ||
171 | } | ||
167 | } | 172 | } |
168 | 173 | ||
169 | dlm_release_root_list(ls); | 174 | dlm_release_root_list(ls); |
170 | 175 | ||
176 | /* | ||
177 | * Purge directory-related requests that are saved in requestqueue. | ||
178 | * All dir requests from before recovery are invalid now due to the dir | ||
179 | * rebuild and will be resent by the requesting nodes. | ||
180 | */ | ||
181 | |||
182 | dlm_purge_requestqueue(ls); | ||
183 | |||
171 | dlm_set_recover_status(ls, DLM_RS_DONE); | 184 | dlm_set_recover_status(ls, DLM_RS_DONE); |
172 | error = dlm_recover_done_wait(ls); | 185 | error = dlm_recover_done_wait(ls); |
173 | if (error) { | 186 | if (error) { |
@@ -199,7 +212,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
199 | 212 | ||
200 | dlm_astd_wake(); | 213 | dlm_astd_wake(); |
201 | 214 | ||
202 | log_debug(ls, "recover %llx done: %u ms", rv->seq, | 215 | log_debug(ls, "recover %llx done: %u ms", |
216 | (unsigned long long)rv->seq, | ||
203 | jiffies_to_msecs(jiffies - start)); | 217 | jiffies_to_msecs(jiffies - start)); |
204 | mutex_unlock(&ls->ls_recoverd_active); | 218 | mutex_unlock(&ls->ls_recoverd_active); |
205 | 219 | ||
@@ -207,11 +221,16 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
207 | 221 | ||
208 | fail: | 222 | fail: |
209 | dlm_release_root_list(ls); | 223 | dlm_release_root_list(ls); |
210 | log_debug(ls, "recover %llx error %d", rv->seq, error); | 224 | log_debug(ls, "recover %llx error %d", |
225 | (unsigned long long)rv->seq, error); | ||
211 | mutex_unlock(&ls->ls_recoverd_active); | 226 | mutex_unlock(&ls->ls_recoverd_active); |
212 | return error; | 227 | return error; |
213 | } | 228 | } |
214 | 229 | ||
230 | /* The dlm_ls_start() that created the rv we take here may already have been | ||
231 | stopped via dlm_ls_stop(); in that case we need to leave the RECOVERY_STOP | ||
232 | flag set. */ | ||
233 | |||
215 | static void do_ls_recovery(struct dlm_ls *ls) | 234 | static void do_ls_recovery(struct dlm_ls *ls) |
216 | { | 235 | { |
217 | struct dlm_recover *rv = NULL; | 236 | struct dlm_recover *rv = NULL; |
@@ -219,7 +238,8 @@ static void do_ls_recovery(struct dlm_ls *ls) | |||
219 | spin_lock(&ls->ls_recover_lock); | 238 | spin_lock(&ls->ls_recover_lock); |
220 | rv = ls->ls_recover_args; | 239 | rv = ls->ls_recover_args; |
221 | ls->ls_recover_args = NULL; | 240 | ls->ls_recover_args = NULL; |
222 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | 241 | if (rv && ls->ls_recover_seq == rv->seq) |
242 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | ||
223 | spin_unlock(&ls->ls_recover_lock); | 243 | spin_unlock(&ls->ls_recover_lock); |
224 | 244 | ||
225 | if (rv) { | 245 | if (rv) { |
diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 7b2b089634a2..65008d79c96d 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c | |||
@@ -30,26 +30,36 @@ struct rq_entry { | |||
30 | * lockspace is enabled on some while still suspended on others. | 30 | * lockspace is enabled on some while still suspended on others. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) | 33 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) |
34 | { | 34 | { |
35 | struct rq_entry *e; | 35 | struct rq_entry *e; |
36 | int length = hd->h_length; | 36 | int length = hd->h_length; |
37 | 37 | int rv = 0; | |
38 | if (dlm_is_removed(ls, nodeid)) | ||
39 | return; | ||
40 | 38 | ||
41 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); | 39 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); |
42 | if (!e) { | 40 | if (!e) { |
43 | log_print("dlm_add_requestqueue: out of memory\n"); | 41 | log_print("dlm_add_requestqueue: out of memory\n"); |
44 | return; | 42 | return 0; |
45 | } | 43 | } |
46 | 44 | ||
47 | e->nodeid = nodeid; | 45 | e->nodeid = nodeid; |
48 | memcpy(e->request, hd, length); | 46 | memcpy(e->request, hd, length); |
49 | 47 | ||
48 | /* We need to check dlm_locking_stopped() after taking the mutex to | ||
49 | avoid a race where dlm_recoverd enables locking and runs | ||
50 | process_requestqueue between our earlier dlm_locking_stopped check | ||
51 | and this addition to the requestqueue. */ | ||
52 | |||
50 | mutex_lock(&ls->ls_requestqueue_mutex); | 53 | mutex_lock(&ls->ls_requestqueue_mutex); |
51 | list_add_tail(&e->list, &ls->ls_requestqueue); | 54 | if (dlm_locking_stopped(ls)) |
55 | list_add_tail(&e->list, &ls->ls_requestqueue); | ||
56 | else { | ||
57 | log_debug(ls, "dlm_add_requestqueue skip from %d", nodeid); | ||
58 | kfree(e); | ||
59 | rv = -EAGAIN; | ||
60 | } | ||
52 | mutex_unlock(&ls->ls_requestqueue_mutex); | 61 | mutex_unlock(&ls->ls_requestqueue_mutex); |
62 | return rv; | ||
53 | } | 63 | } |
54 | 64 | ||
55 | int dlm_process_requestqueue(struct dlm_ls *ls) | 65 | int dlm_process_requestqueue(struct dlm_ls *ls) |
@@ -120,6 +130,10 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) | |||
120 | { | 130 | { |
121 | uint32_t type = ms->m_type; | 131 | uint32_t type = ms->m_type; |
122 | 132 | ||
133 | /* the ls is being cleaned up and freed by release_lockspace */ | ||
134 | if (!ls->ls_count) | ||
135 | return 1; | ||
136 | |||
123 | if (dlm_is_removed(ls, nodeid)) | 137 | if (dlm_is_removed(ls, nodeid)) |
124 | return 1; | 138 | return 1; |
125 | 139 | ||
diff --git a/fs/dlm/requestqueue.h b/fs/dlm/requestqueue.h index 349f0d292d95..6a53ea03335d 100644 --- a/fs/dlm/requestqueue.h +++ b/fs/dlm/requestqueue.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __REQUESTQUEUE_DOT_H__ | 13 | #ifndef __REQUESTQUEUE_DOT_H__ |
14 | #define __REQUESTQUEUE_DOT_H__ | 14 | #define __REQUESTQUEUE_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); | 16 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); |
17 | int dlm_process_requestqueue(struct dlm_ls *ls); | 17 | int dlm_process_requestqueue(struct dlm_ls *ls); |
18 | void dlm_wait_requestqueue(struct dlm_ls *ls); | 18 | void dlm_wait_requestqueue(struct dlm_ls *ls); |
19 | void dlm_purge_requestqueue(struct dlm_ls *ls); | 19 | void dlm_purge_requestqueue(struct dlm_ls *ls); |
diff --git a/fs/dnotify.c b/fs/dnotify.c index 2b0442db67e0..936409fcd939 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | int dir_notify_enable __read_mostly = 1; | 24 | int dir_notify_enable __read_mostly = 1; |
25 | 25 | ||
26 | static kmem_cache_t *dn_cache __read_mostly; | 26 | static struct kmem_cache *dn_cache __read_mostly; |
27 | 27 | ||
28 | static void redo_inode_mask(struct inode *inode) | 28 | static void redo_inode_mask(struct inode *inode) |
29 | { | 29 | { |
@@ -42,7 +42,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) | |||
42 | struct dnotify_struct **prev; | 42 | struct dnotify_struct **prev; |
43 | struct inode *inode; | 43 | struct inode *inode; |
44 | 44 | ||
45 | inode = filp->f_dentry->d_inode; | 45 | inode = filp->f_path.dentry->d_inode; |
46 | if (!S_ISDIR(inode->i_mode)) | 46 | if (!S_ISDIR(inode->i_mode)) |
47 | return; | 47 | return; |
48 | spin_lock(&inode->i_lock); | 48 | spin_lock(&inode->i_lock); |
@@ -74,10 +74,10 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
74 | } | 74 | } |
75 | if (!dir_notify_enable) | 75 | if (!dir_notify_enable) |
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | inode = filp->f_dentry->d_inode; | 77 | inode = filp->f_path.dentry->d_inode; |
78 | if (!S_ISDIR(inode->i_mode)) | 78 | if (!S_ISDIR(inode->i_mode)) |
79 | return -ENOTDIR; | 79 | return -ENOTDIR; |
80 | dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL); | 80 | dn = kmem_cache_alloc(dn_cache, GFP_KERNEL); |
81 | if (dn == NULL) | 81 | if (dn == NULL) |
82 | return -ENOMEM; | 82 | return -ENOMEM; |
83 | spin_lock(&inode->i_lock); | 83 | spin_lock(&inode->i_lock); |
diff --git a/fs/dquot.c b/fs/dquot.c index 9af789567e51..0952cc474d9a 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -131,7 +131,7 @@ static struct quota_format_type *quota_formats; /* List of registered formats */ | |||
131 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; | 131 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; |
132 | 132 | ||
133 | /* SLAB cache for dquot structures */ | 133 | /* SLAB cache for dquot structures */ |
134 | static kmem_cache_t *dquot_cachep; | 134 | static struct kmem_cache *dquot_cachep; |
135 | 135 | ||
136 | int register_quota_format(struct quota_format_type *fmt) | 136 | int register_quota_format(struct quota_format_type *fmt) |
137 | { | 137 | { |
@@ -600,7 +600,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
600 | { | 600 | { |
601 | struct dquot *dquot; | 601 | struct dquot *dquot; |
602 | 602 | ||
603 | dquot = kmem_cache_alloc(dquot_cachep, SLAB_NOFS); | 603 | dquot = kmem_cache_alloc(dquot_cachep, GFP_NOFS); |
604 | if(!dquot) | 604 | if(!dquot) |
605 | return NODQUOT; | 605 | return NODQUOT; |
606 | 606 | ||
@@ -694,9 +694,9 @@ restart: | |||
694 | file_list_lock(); | 694 | file_list_lock(); |
695 | list_for_each(p, &sb->s_files) { | 695 | list_for_each(p, &sb->s_files) { |
696 | struct file *filp = list_entry(p, struct file, f_u.fu_list); | 696 | struct file *filp = list_entry(p, struct file, f_u.fu_list); |
697 | struct inode *inode = filp->f_dentry->d_inode; | 697 | struct inode *inode = filp->f_path.dentry->d_inode; |
698 | if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { | 698 | if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { |
699 | struct dentry *dentry = dget(filp->f_dentry); | 699 | struct dentry *dentry = dget(filp->f_path.dentry); |
700 | file_list_unlock(); | 700 | file_list_unlock(); |
701 | sb->dq_op->initialize(inode, type); | 701 | sb->dq_op->initialize(inode, type); |
702 | dput(dentry); | 702 | dput(dentry); |
@@ -828,6 +828,7 @@ static inline int need_print_warning(struct dquot *dquot) | |||
828 | static void print_warning(struct dquot *dquot, const char warntype) | 828 | static void print_warning(struct dquot *dquot, const char warntype) |
829 | { | 829 | { |
830 | char *msg = NULL; | 830 | char *msg = NULL; |
831 | struct tty_struct *tty; | ||
831 | int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS_B : | 832 | int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS_B : |
832 | ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES_B : 0); | 833 | ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES_B : 0); |
833 | 834 | ||
@@ -835,14 +836,15 @@ static void print_warning(struct dquot *dquot, const char warntype) | |||
835 | return; | 836 | return; |
836 | 837 | ||
837 | mutex_lock(&tty_mutex); | 838 | mutex_lock(&tty_mutex); |
838 | if (!current->signal->tty) | 839 | tty = get_current_tty(); |
840 | if (!tty) | ||
839 | goto out_lock; | 841 | goto out_lock; |
840 | tty_write_message(current->signal->tty, dquot->dq_sb->s_id); | 842 | tty_write_message(tty, dquot->dq_sb->s_id); |
841 | if (warntype == ISOFTWARN || warntype == BSOFTWARN) | 843 | if (warntype == ISOFTWARN || warntype == BSOFTWARN) |
842 | tty_write_message(current->signal->tty, ": warning, "); | 844 | tty_write_message(tty, ": warning, "); |
843 | else | 845 | else |
844 | tty_write_message(current->signal->tty, ": write failed, "); | 846 | tty_write_message(tty, ": write failed, "); |
845 | tty_write_message(current->signal->tty, quotatypes[dquot->dq_type]); | 847 | tty_write_message(tty, quotatypes[dquot->dq_type]); |
846 | switch (warntype) { | 848 | switch (warntype) { |
847 | case IHARDWARN: | 849 | case IHARDWARN: |
848 | msg = " file limit reached.\r\n"; | 850 | msg = " file limit reached.\r\n"; |
@@ -863,7 +865,7 @@ static void print_warning(struct dquot *dquot, const char warntype) | |||
863 | msg = " block quota exceeded.\r\n"; | 865 | msg = " block quota exceeded.\r\n"; |
864 | break; | 866 | break; |
865 | } | 867 | } |
866 | tty_write_message(current->signal->tty, msg); | 868 | tty_write_message(tty, msg); |
867 | out_lock: | 869 | out_lock: |
868 | mutex_unlock(&tty_mutex); | 870 | mutex_unlock(&tty_mutex); |
869 | } | 871 | } |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f63a7755fe86..7196f50fe152 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -628,7 +628,7 @@ int ecryptfs_decrypt_page(struct file *file, struct page *page) | |||
628 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; | 628 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; |
629 | base_extent = (page->index * num_extents_per_page); | 629 | base_extent = (page->index * num_extents_per_page); |
630 | lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, | 630 | lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, |
631 | SLAB_KERNEL); | 631 | GFP_KERNEL); |
632 | if (!lower_page_virt) { | 632 | if (!lower_page_virt) { |
633 | rc = -ENOMEM; | 633 | rc = -ENOMEM; |
634 | ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " | 634 | ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " |
@@ -1334,7 +1334,7 @@ int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | |||
1334 | goto out; | 1334 | goto out; |
1335 | } | 1335 | } |
1336 | /* Released in this function */ | 1336 | /* Released in this function */ |
1337 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER); | 1337 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, GFP_USER); |
1338 | if (!page_virt) { | 1338 | if (!page_virt) { |
1339 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 1339 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); |
1340 | rc = -ENOMEM; | 1340 | rc = -ENOMEM; |
@@ -1493,7 +1493,7 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | |||
1493 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1493 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1494 | 1494 | ||
1495 | /* Read the first page from the underlying file */ | 1495 | /* Read the first page from the underlying file */ |
1496 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER); | 1496 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); |
1497 | if (!page_virt) { | 1497 | if (!page_virt) { |
1498 | rc = -ENOMEM; | 1498 | rc = -ENOMEM; |
1499 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); | 1499 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 52d1e36dc746..329efcd3d8c9 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/dcache.h> | 25 | #include <linux/dcache.h> |
26 | #include <linux/namei.h> | 26 | #include <linux/namei.h> |
27 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
28 | #include <linux/fs_stack.h> | ||
28 | #include "ecryptfs_kernel.h" | 29 | #include "ecryptfs_kernel.h" |
29 | 30 | ||
30 | /** | 31 | /** |
@@ -61,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
61 | struct inode *lower_inode = | 62 | struct inode *lower_inode = |
62 | ecryptfs_inode_to_lower(dentry->d_inode); | 63 | ecryptfs_inode_to_lower(dentry->d_inode); |
63 | 64 | ||
64 | ecryptfs_copy_attr_all(dentry->d_inode, lower_inode); | 65 | fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL); |
65 | } | 66 | } |
66 | out: | 67 | out: |
67 | return rc; | 68 | return rc; |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index f992533d1692..afb64bdbe6ad 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include <keys/user-type.h> | 29 | #include <keys/user-type.h> |
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/fs_stack.h> | ||
32 | #include <linux/namei.h> | ||
31 | #include <linux/scatterlist.h> | 33 | #include <linux/scatterlist.h> |
32 | 34 | ||
33 | /* Version verification for shared data structures w/ userspace */ | 35 | /* Version verification for shared data structures w/ userspace */ |
@@ -227,8 +229,7 @@ struct ecryptfs_inode_info { | |||
227 | /* dentry private data. Each dentry must keep track of a lower | 229 | /* dentry private data. Each dentry must keep track of a lower |
228 | * vfsmount too. */ | 230 | * vfsmount too. */ |
229 | struct ecryptfs_dentry_info { | 231 | struct ecryptfs_dentry_info { |
230 | struct dentry *wdi_dentry; | 232 | struct path lower_path; |
231 | struct vfsmount *lower_mnt; | ||
232 | struct ecryptfs_crypt_stat *crypt_stat; | 233 | struct ecryptfs_crypt_stat *crypt_stat; |
233 | }; | 234 | }; |
234 | 235 | ||
@@ -355,26 +356,26 @@ ecryptfs_set_dentry_private(struct dentry *dentry, | |||
355 | static inline struct dentry * | 356 | static inline struct dentry * |
356 | ecryptfs_dentry_to_lower(struct dentry *dentry) | 357 | ecryptfs_dentry_to_lower(struct dentry *dentry) |
357 | { | 358 | { |
358 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry; | 359 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry; |
359 | } | 360 | } |
360 | 361 | ||
361 | static inline void | 362 | static inline void |
362 | ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry) | 363 | ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry) |
363 | { | 364 | { |
364 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry = | 365 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry = |
365 | lower_dentry; | 366 | lower_dentry; |
366 | } | 367 | } |
367 | 368 | ||
368 | static inline struct vfsmount * | 369 | static inline struct vfsmount * |
369 | ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) | 370 | ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) |
370 | { | 371 | { |
371 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt; | 372 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.mnt; |
372 | } | 373 | } |
373 | 374 | ||
374 | static inline void | 375 | static inline void |
375 | ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt) | 376 | ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt) |
376 | { | 377 | { |
377 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt = | 378 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.mnt = |
378 | lower_mnt; | 379 | lower_mnt; |
379 | } | 380 | } |
380 | 381 | ||
@@ -413,9 +414,6 @@ int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, | |||
413 | const char *name, int length, | 414 | const char *name, int length, |
414 | char **encoded_name); | 415 | char **encoded_name); |
415 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); | 416 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); |
416 | void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src); | ||
417 | void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src); | ||
418 | void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src); | ||
419 | void ecryptfs_dump_hex(char *data, int bytes); | 417 | void ecryptfs_dump_hex(char *data, int bytes); |
420 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, | 418 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, |
421 | int sg_size); | 419 | int sg_size); |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index a92ef05eff8f..c5a2e5298f15 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/security.h> | 30 | #include <linux/security.h> |
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/compat.h> | 32 | #include <linux/compat.h> |
33 | #include <linux/fs_stack.h> | ||
33 | #include "ecryptfs_kernel.h" | 34 | #include "ecryptfs_kernel.h" |
34 | 35 | ||
35 | /** | 36 | /** |
@@ -75,7 +76,7 @@ static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin) | |||
75 | } | 76 | } |
76 | ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos); | 77 | ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos); |
77 | if (expanding_file) { | 78 | if (expanding_file) { |
78 | rc = ecryptfs_truncate(file->f_dentry, new_end_pos); | 79 | rc = ecryptfs_truncate(file->f_path.dentry, new_end_pos); |
79 | if (rc) { | 80 | if (rc) { |
80 | rv = rc; | 81 | rv = rc; |
81 | ecryptfs_printk(KERN_ERR, "Error on attempt to " | 82 | ecryptfs_printk(KERN_ERR, "Error on attempt to " |
@@ -116,8 +117,8 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | |||
116 | if (-EIOCBQUEUED == rc) | 117 | if (-EIOCBQUEUED == rc) |
117 | rc = wait_on_sync_kiocb(iocb); | 118 | rc = wait_on_sync_kiocb(iocb); |
118 | if (rc >= 0) { | 119 | if (rc >= 0) { |
119 | lower_dentry = ecryptfs_dentry_to_lower(file->f_dentry); | 120 | lower_dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); |
120 | lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_dentry); | 121 | lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); |
121 | touch_atime(lower_vfsmount, lower_dentry); | 122 | touch_atime(lower_vfsmount, lower_dentry); |
122 | } | 123 | } |
123 | return rc; | 124 | return rc; |
@@ -176,10 +177,10 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
176 | 177 | ||
177 | lower_file = ecryptfs_file_to_lower(file); | 178 | lower_file = ecryptfs_file_to_lower(file); |
178 | lower_file->f_pos = file->f_pos; | 179 | lower_file->f_pos = file->f_pos; |
179 | inode = file->f_dentry->d_inode; | 180 | inode = file->f_path.dentry->d_inode; |
180 | memset(&buf, 0, sizeof(buf)); | 181 | memset(&buf, 0, sizeof(buf)); |
181 | buf.dirent = dirent; | 182 | buf.dirent = dirent; |
182 | buf.dentry = file->f_dentry; | 183 | buf.dentry = file->f_path.dentry; |
183 | buf.filldir = filldir; | 184 | buf.filldir = filldir; |
184 | retry: | 185 | retry: |
185 | buf.filldir_called = 0; | 186 | buf.filldir_called = 0; |
@@ -192,7 +193,7 @@ retry: | |||
192 | goto retry; | 193 | goto retry; |
193 | file->f_pos = lower_file->f_pos; | 194 | file->f_pos = lower_file->f_pos; |
194 | if (rc >= 0) | 195 | if (rc >= 0) |
195 | ecryptfs_copy_attr_atime(inode, lower_file->f_dentry->d_inode); | 196 | fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode); |
196 | return rc; | 197 | return rc; |
197 | } | 198 | } |
198 | 199 | ||
@@ -239,7 +240,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
239 | int rc = 0; | 240 | int rc = 0; |
240 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 241 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
241 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | 242 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
242 | struct dentry *ecryptfs_dentry = file->f_dentry; | 243 | struct dentry *ecryptfs_dentry = file->f_path.dentry; |
243 | /* Private value of ecryptfs_dentry allocated in | 244 | /* Private value of ecryptfs_dentry allocated in |
244 | * ecryptfs_lookup() */ | 245 | * ecryptfs_lookup() */ |
245 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 246 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
@@ -250,7 +251,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
250 | int lower_flags; | 251 | int lower_flags; |
251 | 252 | ||
252 | /* Released in ecryptfs_release or end of function if failure */ | 253 | /* Released in ecryptfs_release or end of function if failure */ |
253 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL); | 254 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, GFP_KERNEL); |
254 | ecryptfs_set_file_private(file, file_info); | 255 | ecryptfs_set_file_private(file, file_info); |
255 | if (!file_info) { | 256 | if (!file_info) { |
256 | ecryptfs_printk(KERN_ERR, | 257 | ecryptfs_printk(KERN_ERR, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index dfcc68484f47..11f5e5076aef 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/namei.h> | 30 | #include <linux/namei.h> |
31 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
33 | #include <linux/fs_stack.h> | ||
33 | #include "ecryptfs_kernel.h" | 34 | #include "ecryptfs_kernel.h" |
34 | 35 | ||
35 | static struct dentry *lock_parent(struct dentry *dentry) | 36 | static struct dentry *lock_parent(struct dentry *dentry) |
@@ -53,48 +54,6 @@ static void unlock_dir(struct dentry *dir) | |||
53 | dput(dir); | 54 | dput(dir); |
54 | } | 55 | } |
55 | 56 | ||
56 | void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src) | ||
57 | { | ||
58 | i_size_write(dst, i_size_read((struct inode *)src)); | ||
59 | dst->i_blocks = src->i_blocks; | ||
60 | } | ||
61 | |||
62 | void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src) | ||
63 | { | ||
64 | dest->i_atime = src->i_atime; | ||
65 | } | ||
66 | |||
67 | static void ecryptfs_copy_attr_times(struct inode *dest, | ||
68 | const struct inode *src) | ||
69 | { | ||
70 | dest->i_atime = src->i_atime; | ||
71 | dest->i_mtime = src->i_mtime; | ||
72 | dest->i_ctime = src->i_ctime; | ||
73 | } | ||
74 | |||
75 | static void ecryptfs_copy_attr_timesizes(struct inode *dest, | ||
76 | const struct inode *src) | ||
77 | { | ||
78 | dest->i_atime = src->i_atime; | ||
79 | dest->i_mtime = src->i_mtime; | ||
80 | dest->i_ctime = src->i_ctime; | ||
81 | ecryptfs_copy_inode_size(dest, src); | ||
82 | } | ||
83 | |||
84 | void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src) | ||
85 | { | ||
86 | dest->i_mode = src->i_mode; | ||
87 | dest->i_nlink = src->i_nlink; | ||
88 | dest->i_uid = src->i_uid; | ||
89 | dest->i_gid = src->i_gid; | ||
90 | dest->i_rdev = src->i_rdev; | ||
91 | dest->i_atime = src->i_atime; | ||
92 | dest->i_mtime = src->i_mtime; | ||
93 | dest->i_ctime = src->i_ctime; | ||
94 | dest->i_blkbits = src->i_blkbits; | ||
95 | dest->i_flags = src->i_flags; | ||
96 | } | ||
97 | |||
98 | /** | 57 | /** |
99 | * ecryptfs_create_underlying_file | 58 | * ecryptfs_create_underlying_file |
100 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | 59 | * @lower_dir_inode: inode of the parent in the lower fs of the new file |
@@ -171,8 +130,8 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
171 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); | 130 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); |
172 | goto out_lock; | 131 | goto out_lock; |
173 | } | 132 | } |
174 | ecryptfs_copy_attr_timesizes(directory_inode, | 133 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
175 | lower_dir_dentry->d_inode); | 134 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
176 | out_lock: | 135 | out_lock: |
177 | unlock_dir(lower_dir_dentry); | 136 | unlock_dir(lower_dir_dentry); |
178 | out: | 137 | out: |
@@ -196,7 +155,7 @@ static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, | |||
196 | struct ecryptfs_file_info tmp_file_info; | 155 | struct ecryptfs_file_info tmp_file_info; |
197 | 156 | ||
198 | memset(&fake_file, 0, sizeof(fake_file)); | 157 | memset(&fake_file, 0, sizeof(fake_file)); |
199 | fake_file.f_dentry = ecryptfs_dentry; | 158 | fake_file.f_path.dentry = ecryptfs_dentry; |
200 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | 159 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); |
201 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | 160 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); |
202 | ecryptfs_set_file_lower(&fake_file, lower_file); | 161 | ecryptfs_set_file_lower(&fake_file, lower_file); |
@@ -365,11 +324,11 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
365 | "d_name.name = [%s]\n", lower_dentry, | 324 | "d_name.name = [%s]\n", lower_dentry, |
366 | lower_dentry->d_name.name); | 325 | lower_dentry->d_name.name); |
367 | lower_inode = lower_dentry->d_inode; | 326 | lower_inode = lower_dentry->d_inode; |
368 | ecryptfs_copy_attr_atime(dir, lower_dir_dentry->d_inode); | 327 | fsstack_copy_attr_atime(dir, lower_dir_dentry->d_inode); |
369 | BUG_ON(!atomic_read(&lower_dentry->d_count)); | 328 | BUG_ON(!atomic_read(&lower_dentry->d_count)); |
370 | ecryptfs_set_dentry_private(dentry, | 329 | ecryptfs_set_dentry_private(dentry, |
371 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 330 | kmem_cache_alloc(ecryptfs_dentry_info_cache, |
372 | SLAB_KERNEL)); | 331 | GFP_KERNEL)); |
373 | if (!ecryptfs_dentry_to_private(dentry)) { | 332 | if (!ecryptfs_dentry_to_private(dentry)) { |
374 | rc = -ENOMEM; | 333 | rc = -ENOMEM; |
375 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " | 334 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " |
@@ -404,7 +363,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
404 | /* Released in this function */ | 363 | /* Released in this function */ |
405 | page_virt = | 364 | page_virt = |
406 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | 365 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, |
407 | SLAB_USER); | 366 | GFP_USER); |
408 | if (!page_virt) { | 367 | if (!page_virt) { |
409 | rc = -ENOMEM; | 368 | rc = -ENOMEM; |
410 | ecryptfs_printk(KERN_ERR, | 369 | ecryptfs_printk(KERN_ERR, |
@@ -462,7 +421,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
462 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | 421 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); |
463 | if (rc) | 422 | if (rc) |
464 | goto out_lock; | 423 | goto out_lock; |
465 | ecryptfs_copy_attr_timesizes(dir, lower_new_dentry->d_inode); | 424 | fsstack_copy_attr_times(dir, lower_new_dentry->d_inode); |
425 | fsstack_copy_inode_size(dir, lower_new_dentry->d_inode); | ||
466 | old_dentry->d_inode->i_nlink = | 426 | old_dentry->d_inode->i_nlink = |
467 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; | 427 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; |
468 | i_size_write(new_dentry->d_inode, file_size_save); | 428 | i_size_write(new_dentry->d_inode, file_size_save); |
@@ -488,7 +448,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | |||
488 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | 448 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); |
489 | goto out_unlock; | 449 | goto out_unlock; |
490 | } | 450 | } |
491 | ecryptfs_copy_attr_times(dir, lower_dir_inode); | 451 | fsstack_copy_attr_times(dir, lower_dir_inode); |
492 | dentry->d_inode->i_nlink = | 452 | dentry->d_inode->i_nlink = |
493 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; | 453 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; |
494 | dentry->d_inode->i_ctime = dir->i_ctime; | 454 | dentry->d_inode->i_ctime = dir->i_ctime; |
@@ -527,7 +487,8 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
527 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 487 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); |
528 | if (rc) | 488 | if (rc) |
529 | goto out_lock; | 489 | goto out_lock; |
530 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | 490 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
491 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); | ||
531 | out_lock: | 492 | out_lock: |
532 | unlock_dir(lower_dir_dentry); | 493 | unlock_dir(lower_dir_dentry); |
533 | dput(lower_dentry); | 494 | dput(lower_dentry); |
@@ -550,7 +511,8 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
550 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 511 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); |
551 | if (rc) | 512 | if (rc) |
552 | goto out; | 513 | goto out; |
553 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | 514 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
515 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); | ||
554 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 516 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
555 | out: | 517 | out: |
556 | unlock_dir(lower_dir_dentry); | 518 | unlock_dir(lower_dir_dentry); |
@@ -573,7 +535,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
573 | dput(lower_dentry); | 535 | dput(lower_dentry); |
574 | if (!rc) | 536 | if (!rc) |
575 | d_delete(lower_dentry); | 537 | d_delete(lower_dentry); |
576 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); | 538 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
577 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 539 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
578 | unlock_dir(lower_dir_dentry); | 540 | unlock_dir(lower_dir_dentry); |
579 | if (!rc) | 541 | if (!rc) |
@@ -597,7 +559,8 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
597 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 559 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); |
598 | if (rc) | 560 | if (rc) |
599 | goto out; | 561 | goto out; |
600 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | 562 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
563 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); | ||
601 | out: | 564 | out: |
602 | unlock_dir(lower_dir_dentry); | 565 | unlock_dir(lower_dir_dentry); |
603 | if (!dentry->d_inode) | 566 | if (!dentry->d_inode) |
@@ -626,9 +589,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
626 | lower_new_dir_dentry->d_inode, lower_new_dentry); | 589 | lower_new_dir_dentry->d_inode, lower_new_dentry); |
627 | if (rc) | 590 | if (rc) |
628 | goto out_lock; | 591 | goto out_lock; |
629 | ecryptfs_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); | 592 | fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); |
630 | if (new_dir != old_dir) | 593 | if (new_dir != old_dir) |
631 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 594 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL); |
632 | out_lock: | 595 | out_lock: |
633 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 596 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
634 | dput(lower_new_dentry->d_parent); | 597 | dput(lower_new_dentry->d_parent); |
@@ -684,8 +647,8 @@ ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) | |||
684 | rc = -EFAULT; | 647 | rc = -EFAULT; |
685 | } | 648 | } |
686 | kfree(decoded_name); | 649 | kfree(decoded_name); |
687 | ecryptfs_copy_attr_atime(dentry->d_inode, | 650 | fsstack_copy_attr_atime(dentry->d_inode, |
688 | lower_dentry->d_inode); | 651 | lower_dentry->d_inode); |
689 | } | 652 | } |
690 | out_free_lower_buf: | 653 | out_free_lower_buf: |
691 | kfree(lower_buf); | 654 | kfree(lower_buf); |
@@ -791,11 +754,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
791 | * the file in the underlying filesystem so that the | 754 | * the file in the underlying filesystem so that the |
792 | * truncation has an effect there as well. */ | 755 | * truncation has an effect there as well. */ |
793 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); | 756 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); |
794 | fake_ecryptfs_file.f_dentry = dentry; | 757 | fake_ecryptfs_file.f_path.dentry = dentry; |
795 | /* Released at out_free: label */ | 758 | /* Released at out_free: label */ |
796 | ecryptfs_set_file_private(&fake_ecryptfs_file, | 759 | ecryptfs_set_file_private(&fake_ecryptfs_file, |
797 | kmem_cache_alloc(ecryptfs_file_info_cache, | 760 | kmem_cache_alloc(ecryptfs_file_info_cache, |
798 | SLAB_KERNEL)); | 761 | GFP_KERNEL)); |
799 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | 762 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { |
800 | rc = -ENOMEM; | 763 | rc = -ENOMEM; |
801 | goto out; | 764 | goto out; |
@@ -915,7 +878,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
915 | } | 878 | } |
916 | rc = notify_change(lower_dentry, ia); | 879 | rc = notify_change(lower_dentry, ia); |
917 | out: | 880 | out: |
918 | ecryptfs_copy_attr_all(inode, lower_inode); | 881 | fsstack_copy_attr_all(inode, lower_inode, NULL); |
919 | return rc; | 882 | return rc; |
920 | } | 883 | } |
921 | 884 | ||
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index c3746f56d162..745c0f1bfbbd 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -207,7 +207,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
208 | * at end of function upon failure */ | 208 | * at end of function upon failure */ |
209 | auth_tok_list_item = | 209 | auth_tok_list_item = |
210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL); | 210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); |
211 | if (!auth_tok_list_item) { | 211 | if (!auth_tok_list_item) { |
212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
213 | rc = -ENOMEM; | 213 | rc = -ENOMEM; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index a78d87d14baf..d0541ae8faba 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/key.h> | 36 | #include <linux/key.h> |
37 | #include <linux/parser.h> | 37 | #include <linux/parser.h> |
38 | #include <linux/fs_stack.h> | ||
38 | #include "ecryptfs_kernel.h" | 39 | #include "ecryptfs_kernel.h" |
39 | 40 | ||
40 | /** | 41 | /** |
@@ -112,10 +113,10 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
112 | d_add(dentry, inode); | 113 | d_add(dentry, inode); |
113 | else | 114 | else |
114 | d_instantiate(dentry, inode); | 115 | d_instantiate(dentry, inode); |
115 | ecryptfs_copy_attr_all(inode, lower_inode); | 116 | fsstack_copy_attr_all(inode, lower_inode, NULL); |
116 | /* This size will be overwritten for real files w/ headers and | 117 | /* This size will be overwritten for real files w/ headers and |
117 | * other metadata */ | 118 | * other metadata */ |
118 | ecryptfs_copy_inode_size(inode, lower_inode); | 119 | fsstack_copy_inode_size(inode, lower_inode); |
119 | out: | 120 | out: |
120 | return rc; | 121 | return rc; |
121 | } | 122 | } |
@@ -378,7 +379,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
378 | /* Released in ecryptfs_put_super() */ | 379 | /* Released in ecryptfs_put_super() */ |
379 | ecryptfs_set_superblock_private(sb, | 380 | ecryptfs_set_superblock_private(sb, |
380 | kmem_cache_alloc(ecryptfs_sb_info_cache, | 381 | kmem_cache_alloc(ecryptfs_sb_info_cache, |
381 | SLAB_KERNEL)); | 382 | GFP_KERNEL)); |
382 | if (!ecryptfs_superblock_to_private(sb)) { | 383 | if (!ecryptfs_superblock_to_private(sb)) { |
383 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | 384 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); |
384 | rc = -ENOMEM; | 385 | rc = -ENOMEM; |
@@ -402,7 +403,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
402 | /* through deactivate_super(sb) from get_sb_nodev() */ | 403 | /* through deactivate_super(sb) from get_sb_nodev() */ |
403 | ecryptfs_set_dentry_private(sb->s_root, | 404 | ecryptfs_set_dentry_private(sb->s_root, |
404 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 405 | kmem_cache_alloc(ecryptfs_dentry_info_cache, |
405 | SLAB_KERNEL)); | 406 | GFP_KERNEL)); |
406 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | 407 | if (!ecryptfs_dentry_to_private(sb->s_root)) { |
407 | ecryptfs_printk(KERN_ERR, | 408 | ecryptfs_printk(KERN_ERR, |
408 | "dentry_info_cache alloc failed\n"); | 409 | "dentry_info_cache alloc failed\n"); |
@@ -546,7 +547,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) | |||
546 | } | 547 | } |
547 | 548 | ||
548 | static struct ecryptfs_cache_info { | 549 | static struct ecryptfs_cache_info { |
549 | kmem_cache_t **cache; | 550 | struct kmem_cache **cache; |
550 | const char *name; | 551 | const char *name; |
551 | size_t size; | 552 | size_t size; |
552 | void (*ctor)(void*, struct kmem_cache *, unsigned long); | 553 | void (*ctor)(void*, struct kmem_cache *, unsigned long); |
@@ -691,7 +692,7 @@ static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) | |||
691 | 692 | ||
692 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); | 693 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); |
693 | 694 | ||
694 | struct ecryptfs_version_str_map_elem { | 695 | static struct ecryptfs_version_str_map_elem { |
695 | u32 flag; | 696 | u32 flag; |
696 | char *str; | 697 | char *str; |
697 | } ecryptfs_version_str_map[] = { | 698 | } ecryptfs_version_str_map[] = { |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 924dd90a4cf5..06843d24f239 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -51,7 +51,7 @@ static struct page *ecryptfs_get1page(struct file *file, int index) | |||
51 | struct inode *inode; | 51 | struct inode *inode; |
52 | struct address_space *mapping; | 52 | struct address_space *mapping; |
53 | 53 | ||
54 | dentry = file->f_dentry; | 54 | dentry = file->f_path.dentry; |
55 | inode = dentry->d_inode; | 55 | inode = dentry->d_inode; |
56 | mapping = inode->i_mapping; | 56 | mapping = inode->i_mapping; |
57 | page = read_cache_page(mapping, index, | 57 | page = read_cache_page(mapping, index, |
@@ -84,7 +84,7 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros); | |||
84 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | 84 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length) |
85 | { | 85 | { |
86 | int rc = 0; | 86 | int rc = 0; |
87 | struct dentry *dentry = file->f_dentry; | 87 | struct dentry *dentry = file->f_path.dentry; |
88 | struct inode *inode = dentry->d_inode; | 88 | struct inode *inode = dentry->d_inode; |
89 | pgoff_t old_end_page_index = 0; | 89 | pgoff_t old_end_page_index = 0; |
90 | pgoff_t index = old_end_page_index; | 90 | pgoff_t index = old_end_page_index; |
@@ -218,7 +218,7 @@ int ecryptfs_do_readpage(struct file *file, struct page *page, | |||
218 | char *lower_page_data; | 218 | char *lower_page_data; |
219 | const struct address_space_operations *lower_a_ops; | 219 | const struct address_space_operations *lower_a_ops; |
220 | 220 | ||
221 | dentry = file->f_dentry; | 221 | dentry = file->f_path.dentry; |
222 | lower_file = ecryptfs_file_to_lower(file); | 222 | lower_file = ecryptfs_file_to_lower(file); |
223 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 223 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
224 | inode = dentry->d_inode; | 224 | inode = dentry->d_inode; |
@@ -275,9 +275,9 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
275 | int rc = 0; | 275 | int rc = 0; |
276 | struct ecryptfs_crypt_stat *crypt_stat; | 276 | struct ecryptfs_crypt_stat *crypt_stat; |
277 | 277 | ||
278 | BUG_ON(!(file && file->f_dentry && file->f_dentry->d_inode)); | 278 | BUG_ON(!(file && file->f_path.dentry && file->f_path.dentry->d_inode)); |
279 | crypt_stat = | 279 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) |
280 | &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat; | 280 | ->crypt_stat; |
281 | if (!crypt_stat | 281 | if (!crypt_stat |
282 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED) | 282 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED) |
283 | || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | 283 | || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { |
@@ -638,8 +638,8 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
638 | lower_inode = ecryptfs_inode_to_lower(inode); | 638 | lower_inode = ecryptfs_inode_to_lower(inode); |
639 | lower_file = ecryptfs_file_to_lower(file); | 639 | lower_file = ecryptfs_file_to_lower(file); |
640 | mutex_lock(&lower_inode->i_mutex); | 640 | mutex_lock(&lower_inode->i_mutex); |
641 | crypt_stat = | 641 | crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode) |
642 | &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat; | 642 | ->crypt_stat; |
643 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | 643 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { |
644 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | 644 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " |
645 | "crypt_stat at memory location [%p]\n", crypt_stat); | 645 | "crypt_stat at memory location [%p]\n", crypt_stat); |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 825757ae4867..eaa5daaf106e 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -50,7 +50,7 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) | |||
50 | struct inode *inode = NULL; | 50 | struct inode *inode = NULL; |
51 | 51 | ||
52 | ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, | 52 | ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, |
53 | SLAB_KERNEL); | 53 | GFP_KERNEL); |
54 | if (unlikely(!ecryptfs_inode)) | 54 | if (unlikely(!ecryptfs_inode)) |
55 | goto out; | 55 | goto out; |
56 | ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); | 56 | ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); |
diff --git a/fs/efs/dir.c b/fs/efs/dir.c index 17f5b2d3c16a..b46c488eefc8 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c | |||
@@ -20,7 +20,7 @@ struct inode_operations efs_dir_inode_operations = { | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { | 22 | static int efs_readdir(struct file *filp, void *dirent, filldir_t filldir) { |
23 | struct inode *inode = filp->f_dentry->d_inode; | 23 | struct inode *inode = filp->f_path.dentry->d_inode; |
24 | struct buffer_head *bh; | 24 | struct buffer_head *bh; |
25 | 25 | ||
26 | struct efs_dir *dirblock; | 26 | struct efs_dir *dirblock; |
diff --git a/fs/efs/super.c b/fs/efs/super.c index b3f50651eb6b..dfebf21289f4 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c | |||
@@ -52,12 +52,12 @@ static struct pt_types sgi_pt_types[] = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | 54 | ||
55 | static kmem_cache_t * efs_inode_cachep; | 55 | static struct kmem_cache * efs_inode_cachep; |
56 | 56 | ||
57 | static struct inode *efs_alloc_inode(struct super_block *sb) | 57 | static struct inode *efs_alloc_inode(struct super_block *sb) |
58 | { | 58 | { |
59 | struct efs_inode_info *ei; | 59 | struct efs_inode_info *ei; |
60 | ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, SLAB_KERNEL); | 60 | ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL); |
61 | if (!ei) | 61 | if (!ei) |
62 | return NULL; | 62 | return NULL; |
63 | return &ei->vfs_inode; | 63 | return &ei->vfs_inode; |
@@ -68,7 +68,7 @@ static void efs_destroy_inode(struct inode *inode) | |||
68 | kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); | 68 | kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 71 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
72 | { | 72 | { |
73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; | 73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; |
74 | 74 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index ae228ec54e94..3ae644e7e860 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -283,10 +283,10 @@ static struct mutex epmutex; | |||
283 | static struct poll_safewake psw; | 283 | static struct poll_safewake psw; |
284 | 284 | ||
285 | /* Slab cache used to allocate "struct epitem" */ | 285 | /* Slab cache used to allocate "struct epitem" */ |
286 | static kmem_cache_t *epi_cache __read_mostly; | 286 | static struct kmem_cache *epi_cache __read_mostly; |
287 | 287 | ||
288 | /* Slab cache used to allocate "struct eppoll_entry" */ | 288 | /* Slab cache used to allocate "struct eppoll_entry" */ |
289 | static kmem_cache_t *pwq_cache __read_mostly; | 289 | static struct kmem_cache *pwq_cache __read_mostly; |
290 | 290 | ||
291 | /* Virtual fs used to allocate inodes for eventpoll files */ | 291 | /* Virtual fs used to allocate inodes for eventpoll files */ |
292 | static struct vfsmount *eventpoll_mnt __read_mostly; | 292 | static struct vfsmount *eventpoll_mnt __read_mostly; |
@@ -795,8 +795,8 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile, | |||
795 | goto eexit_4; | 795 | goto eexit_4; |
796 | dentry->d_op = &eventpollfs_dentry_operations; | 796 | dentry->d_op = &eventpollfs_dentry_operations; |
797 | d_add(dentry, inode); | 797 | d_add(dentry, inode); |
798 | file->f_vfsmnt = mntget(eventpoll_mnt); | 798 | file->f_path.mnt = mntget(eventpoll_mnt); |
799 | file->f_dentry = dentry; | 799 | file->f_path.dentry = dentry; |
800 | file->f_mapping = inode->i_mapping; | 800 | file->f_mapping = inode->i_mapping; |
801 | 801 | ||
802 | file->f_pos = 0; | 802 | file->f_pos = 0; |
@@ -961,7 +961,7 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, | |||
961 | struct epitem *epi = ep_item_from_epqueue(pt); | 961 | struct epitem *epi = ep_item_from_epqueue(pt); |
962 | struct eppoll_entry *pwq; | 962 | struct eppoll_entry *pwq; |
963 | 963 | ||
964 | if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, SLAB_KERNEL))) { | 964 | if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) { |
965 | init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); | 965 | init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); |
966 | pwq->whead = whead; | 966 | pwq->whead = whead; |
967 | pwq->base = epi; | 967 | pwq->base = epi; |
@@ -1004,7 +1004,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1004 | struct ep_pqueue epq; | 1004 | struct ep_pqueue epq; |
1005 | 1005 | ||
1006 | error = -ENOMEM; | 1006 | error = -ENOMEM; |
1007 | if (!(epi = kmem_cache_alloc(epi_cache, SLAB_KERNEL))) | 1007 | if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL))) |
1008 | goto eexit_1; | 1008 | goto eexit_1; |
1009 | 1009 | ||
1010 | /* Item initialization follow here ... */ | 1010 | /* Item initialization follow here ... */ |
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/binfmts.h> | 38 | #include <linux/binfmts.h> |
39 | #include <linux/swap.h> | 39 | #include <linux/swap.h> |
40 | #include <linux/utsname.h> | 40 | #include <linux/utsname.h> |
41 | #include <linux/pid_namespace.h> | ||
41 | #include <linux/module.h> | 42 | #include <linux/module.h> |
42 | #include <linux/namei.h> | 43 | #include <linux/namei.h> |
43 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
@@ -404,7 +405,7 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
404 | bprm->loader += stack_base; | 405 | bprm->loader += stack_base; |
405 | bprm->exec += stack_base; | 406 | bprm->exec += stack_base; |
406 | 407 | ||
407 | mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); | 408 | mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
408 | if (!mpnt) | 409 | if (!mpnt) |
409 | return -ENOMEM; | 410 | return -ENOMEM; |
410 | 411 | ||
@@ -620,8 +621,8 @@ static int de_thread(struct task_struct *tsk) | |||
620 | * Reparenting needs write_lock on tasklist_lock, | 621 | * Reparenting needs write_lock on tasklist_lock, |
621 | * so it is safe to do it under read_lock. | 622 | * so it is safe to do it under read_lock. |
622 | */ | 623 | */ |
623 | if (unlikely(tsk->group_leader == child_reaper)) | 624 | if (unlikely(tsk->group_leader == child_reaper(tsk))) |
624 | child_reaper = tsk; | 625 | tsk->nsproxy->pid_ns->child_reaper = tsk; |
625 | 626 | ||
626 | zap_other_threads(tsk); | 627 | zap_other_threads(tsk); |
627 | read_unlock(&tasklist_lock); | 628 | read_unlock(&tasklist_lock); |
@@ -782,7 +783,7 @@ static void flush_old_files(struct files_struct * files) | |||
782 | j++; | 783 | j++; |
783 | i = j * __NFDBITS; | 784 | i = j * __NFDBITS; |
784 | fdt = files_fdtable(files); | 785 | fdt = files_fdtable(files); |
785 | if (i >= fdt->max_fds || i >= fdt->max_fdset) | 786 | if (i >= fdt->max_fds) |
786 | break; | 787 | break; |
787 | set = fdt->close_on_exec->fds_bits[j]; | 788 | set = fdt->close_on_exec->fds_bits[j]; |
788 | if (!set) | 789 | if (!set) |
@@ -912,7 +913,7 @@ EXPORT_SYMBOL(flush_old_exec); | |||
912 | int prepare_binprm(struct linux_binprm *bprm) | 913 | int prepare_binprm(struct linux_binprm *bprm) |
913 | { | 914 | { |
914 | int mode; | 915 | int mode; |
915 | struct inode * inode = bprm->file->f_dentry->d_inode; | 916 | struct inode * inode = bprm->file->f_path.dentry->d_inode; |
916 | int retval; | 917 | int retval; |
917 | 918 | ||
918 | mode = inode->i_mode; | 919 | mode = inode->i_mode; |
@@ -922,7 +923,7 @@ int prepare_binprm(struct linux_binprm *bprm) | |||
922 | bprm->e_uid = current->euid; | 923 | bprm->e_uid = current->euid; |
923 | bprm->e_gid = current->egid; | 924 | bprm->e_gid = current->egid; |
924 | 925 | ||
925 | if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) { | 926 | if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { |
926 | /* Set-uid? */ | 927 | /* Set-uid? */ |
927 | if (mode & S_ISUID) { | 928 | if (mode & S_ISUID) { |
928 | current->personality &= ~PER_CLEAR_ON_SETID; | 929 | current->personality &= ~PER_CLEAR_ON_SETID; |
@@ -1515,13 +1516,14 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1515 | ispipe = 1; | 1516 | ispipe = 1; |
1516 | } else | 1517 | } else |
1517 | file = filp_open(corename, | 1518 | file = filp_open(corename, |
1518 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); | 1519 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1520 | 0600); | ||
1519 | if (IS_ERR(file)) | 1521 | if (IS_ERR(file)) |
1520 | goto fail_unlock; | 1522 | goto fail_unlock; |
1521 | inode = file->f_dentry->d_inode; | 1523 | inode = file->f_path.dentry->d_inode; |
1522 | if (inode->i_nlink > 1) | 1524 | if (inode->i_nlink > 1) |
1523 | goto close_fail; /* multiple links - don't dump */ | 1525 | goto close_fail; /* multiple links - don't dump */ |
1524 | if (!ispipe && d_unhashed(file->f_dentry)) | 1526 | if (!ispipe && d_unhashed(file->f_path.dentry)) |
1525 | goto close_fail; | 1527 | goto close_fail; |
1526 | 1528 | ||
1527 | /* AK: actually i see no reason to not allow this for named pipes etc., | 1529 | /* AK: actually i see no reason to not allow this for named pipes etc., |
@@ -1532,7 +1534,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1532 | goto close_fail; | 1534 | goto close_fail; |
1533 | if (!file->f_op->write) | 1535 | if (!file->f_op->write) |
1534 | goto close_fail; | 1536 | goto close_fail; |
1535 | if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0) | 1537 | if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) |
1536 | goto close_fail; | 1538 | goto close_fail; |
1537 | 1539 | ||
1538 | retval = binfmt->core_dump(signr, regs, file); | 1540 | retval = binfmt->core_dump(signr, regs, file); |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 3e7a84a1e509..0b02ba9642d2 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -248,7 +248,7 @@ static int | |||
248 | ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) | 248 | ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) |
249 | { | 249 | { |
250 | loff_t pos = filp->f_pos; | 250 | loff_t pos = filp->f_pos; |
251 | struct inode *inode = filp->f_dentry->d_inode; | 251 | struct inode *inode = filp->f_path.dentry->d_inode; |
252 | struct super_block *sb = inode->i_sb; | 252 | struct super_block *sb = inode->i_sb; |
253 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | 253 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
254 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 254 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 1dfba77eab10..4b099d310712 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -44,6 +44,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
44 | if (!S_ISDIR(inode->i_mode)) | 44 | if (!S_ISDIR(inode->i_mode)) |
45 | flags &= ~EXT2_DIRSYNC_FL; | 45 | flags &= ~EXT2_DIRSYNC_FL; |
46 | 46 | ||
47 | mutex_lock(&inode->i_mutex); | ||
47 | oldflags = ei->i_flags; | 48 | oldflags = ei->i_flags; |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -53,13 +54,16 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
53 | * This test looks nicer. Thanks to Pauline Middelink | 54 | * This test looks nicer. Thanks to Pauline Middelink |
54 | */ | 55 | */ |
55 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { | 56 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { |
56 | if (!capable(CAP_LINUX_IMMUTABLE)) | 57 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
58 | mutex_unlock(&inode->i_mutex); | ||
57 | return -EPERM; | 59 | return -EPERM; |
60 | } | ||
58 | } | 61 | } |
59 | 62 | ||
60 | flags = flags & EXT2_FL_USER_MODIFIABLE; | 63 | flags = flags & EXT2_FL_USER_MODIFIABLE; |
61 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; | 64 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; |
62 | ei->i_flags = flags; | 65 | ei->i_flags = flags; |
66 | mutex_unlock(&inode->i_mutex); | ||
63 | 67 | ||
64 | ext2_set_inode_flags(inode); | 68 | ext2_set_inode_flags(inode); |
65 | inode->i_ctime = CURRENT_TIME_SEC; | 69 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -86,7 +90,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
86 | #ifdef CONFIG_COMPAT | 90 | #ifdef CONFIG_COMPAT |
87 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 91 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
88 | { | 92 | { |
89 | struct inode *inode = file->f_dentry->d_inode; | 93 | struct inode *inode = file->f_path.dentry->d_inode; |
90 | int ret; | 94 | int ret; |
91 | 95 | ||
92 | /* These are just misnamed, they actually get/put from/to user an int */ | 96 | /* These are just misnamed, they actually get/put from/to user an int */ |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index d8b9abd95d07..6347c2dbdd81 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -135,12 +135,12 @@ static void ext2_put_super (struct super_block * sb) | |||
135 | return; | 135 | return; |
136 | } | 136 | } |
137 | 137 | ||
138 | static kmem_cache_t * ext2_inode_cachep; | 138 | static struct kmem_cache * ext2_inode_cachep; |
139 | 139 | ||
140 | static struct inode *ext2_alloc_inode(struct super_block *sb) | 140 | static struct inode *ext2_alloc_inode(struct super_block *sb) |
141 | { | 141 | { |
142 | struct ext2_inode_info *ei; | 142 | struct ext2_inode_info *ei; |
143 | ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, SLAB_KERNEL); | 143 | ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); |
144 | if (!ei) | 144 | if (!ei) |
145 | return NULL; | 145 | return NULL; |
146 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 146 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
@@ -156,7 +156,7 @@ static void ext2_destroy_inode(struct inode *inode) | |||
156 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); | 156 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); |
157 | } | 157 | } |
158 | 158 | ||
159 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 159 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
160 | { | 160 | { |
161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; | 161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; |
162 | 162 | ||
@@ -597,8 +597,6 @@ static int ext2_check_descriptors (struct super_block * sb) | |||
597 | return 1; | 597 | return 1; |
598 | } | 598 | } |
599 | 599 | ||
600 | #define log2(n) ffz(~(n)) | ||
601 | |||
602 | /* | 600 | /* |
603 | * Maximal file size. There is a direct, and {,double-,triple-}indirect | 601 | * Maximal file size. There is a direct, and {,double-,triple-}indirect |
604 | * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. | 602 | * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. |
@@ -834,9 +832,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
834 | sbi->s_sbh = bh; | 832 | sbi->s_sbh = bh; |
835 | sbi->s_mount_state = le16_to_cpu(es->s_state); | 833 | sbi->s_mount_state = le16_to_cpu(es->s_state); |
836 | sbi->s_addr_per_block_bits = | 834 | sbi->s_addr_per_block_bits = |
837 | log2 (EXT2_ADDR_PER_BLOCK(sb)); | 835 | ilog2 (EXT2_ADDR_PER_BLOCK(sb)); |
838 | sbi->s_desc_per_block_bits = | 836 | sbi->s_desc_per_block_bits = |
839 | log2 (EXT2_DESC_PER_BLOCK(sb)); | 837 | ilog2 (EXT2_DESC_PER_BLOCK(sb)); |
840 | 838 | ||
841 | if (sb->s_magic != EXT2_SUPER_MAGIC) | 839 | if (sb->s_magic != EXT2_SUPER_MAGIC) |
842 | goto cantfind_ext2; | 840 | goto cantfind_ext2; |
@@ -1090,8 +1088,10 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1090 | { | 1088 | { |
1091 | struct super_block *sb = dentry->d_sb; | 1089 | struct super_block *sb = dentry->d_sb; |
1092 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 1090 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
1091 | struct ext2_super_block *es = sbi->s_es; | ||
1093 | unsigned long overhead; | 1092 | unsigned long overhead; |
1094 | int i; | 1093 | int i; |
1094 | u64 fsid; | ||
1095 | 1095 | ||
1096 | if (test_opt (sb, MINIX_DF)) | 1096 | if (test_opt (sb, MINIX_DF)) |
1097 | overhead = 0; | 1097 | overhead = 0; |
@@ -1104,7 +1104,7 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1104 | * All of the blocks before first_data_block are | 1104 | * All of the blocks before first_data_block are |
1105 | * overhead | 1105 | * overhead |
1106 | */ | 1106 | */ |
1107 | overhead = le32_to_cpu(sbi->s_es->s_first_data_block); | 1107 | overhead = le32_to_cpu(es->s_first_data_block); |
1108 | 1108 | ||
1109 | /* | 1109 | /* |
1110 | * Add the overhead attributed to the superblock and | 1110 | * Add the overhead attributed to the superblock and |
@@ -1125,14 +1125,18 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1125 | 1125 | ||
1126 | buf->f_type = EXT2_SUPER_MAGIC; | 1126 | buf->f_type = EXT2_SUPER_MAGIC; |
1127 | buf->f_bsize = sb->s_blocksize; | 1127 | buf->f_bsize = sb->s_blocksize; |
1128 | buf->f_blocks = le32_to_cpu(sbi->s_es->s_blocks_count) - overhead; | 1128 | buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; |
1129 | buf->f_bfree = ext2_count_free_blocks(sb); | 1129 | buf->f_bfree = ext2_count_free_blocks(sb); |
1130 | buf->f_bavail = buf->f_bfree - le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1130 | buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); |
1131 | if (buf->f_bfree < le32_to_cpu(sbi->s_es->s_r_blocks_count)) | 1131 | if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) |
1132 | buf->f_bavail = 0; | 1132 | buf->f_bavail = 0; |
1133 | buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); | 1133 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
1134 | buf->f_ffree = ext2_count_free_inodes (sb); | 1134 | buf->f_ffree = ext2_count_free_inodes(sb); |
1135 | buf->f_namelen = EXT2_NAME_LEN; | 1135 | buf->f_namelen = EXT2_NAME_LEN; |
1136 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
1137 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
1138 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
1139 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
1136 | return 0; | 1140 | return 0; |
1137 | } | 1141 | } |
1138 | 1142 | ||
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index af52a7f8b291..247efd0b51d6 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -342,12 +342,9 @@ static void ext2_xattr_update_super_block(struct super_block *sb) | |||
342 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) | 342 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) |
343 | return; | 343 | return; |
344 | 344 | ||
345 | lock_super(sb); | 345 | EXT2_SET_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR); |
346 | EXT2_SB(sb)->s_es->s_feature_compat |= | ||
347 | cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR); | ||
348 | sb->s_dirt = 1; | 346 | sb->s_dirt = 1; |
349 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); | 347 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); |
350 | unlock_super(sb); | ||
351 | } | 348 | } |
352 | 349 | ||
353 | /* | 350 | /* |
diff --git a/fs/ext3/Makefile b/fs/ext3/Makefile index 704cd44a40c2..e77766a8b3f0 100644 --- a/fs/ext3/Makefile +++ b/fs/ext3/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-$(CONFIG_EXT3_FS) += ext3.o | 5 | obj-$(CONFIG_EXT3_FS) += ext3.o |
6 | 6 | ||
7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o ext3_jbd.o |
9 | 9 | ||
10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o | 11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index b41a7d7e20f0..22161740ba29 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -144,7 +144,7 @@ restart: | |||
144 | 144 | ||
145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
146 | while (n) { | 146 | while (n) { |
147 | rsv = list_entry(n, struct ext3_reserve_window_node, rsv_node); | 147 | rsv = rb_entry(n, struct ext3_reserve_window_node, rsv_node); |
148 | if (verbose) | 148 | if (verbose) |
149 | printk("reservation window 0x%p " | 149 | printk("reservation window 0x%p " |
150 | "start: %lu, end: %lu\n", | 150 | "start: %lu, end: %lu\n", |
@@ -730,7 +730,7 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, | |||
730 | here = 0; | 730 | here = 0; |
731 | 731 | ||
732 | p = ((char *)bh->b_data) + (here >> 3); | 732 | p = ((char *)bh->b_data) + (here >> 3); |
733 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 733 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
734 | next = (r - ((char *)bh->b_data)) << 3; | 734 | next = (r - ((char *)bh->b_data)) << 3; |
735 | 735 | ||
736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) | 736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) |
@@ -949,7 +949,7 @@ static int find_next_reservable_window( | |||
949 | 949 | ||
950 | prev = rsv; | 950 | prev = rsv; |
951 | next = rb_next(&rsv->rsv_node); | 951 | next = rb_next(&rsv->rsv_node); |
952 | rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); | 952 | rsv = rb_entry(next,struct ext3_reserve_window_node,rsv_node); |
953 | 953 | ||
954 | /* | 954 | /* |
955 | * Reached the last reservation, we can just append to the | 955 | * Reached the last reservation, we can just append to the |
@@ -1148,7 +1148,7 @@ retry: | |||
1148 | * check if the first free block is within the | 1148 | * check if the first free block is within the |
1149 | * free space we just reserved | 1149 | * free space we just reserved |
1150 | */ | 1150 | */ |
1151 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1151 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1152 | return 0; /* success */ | 1152 | return 0; /* success */ |
1153 | /* | 1153 | /* |
1154 | * if the first free bit we found is out of the reservable space | 1154 | * if the first free bit we found is out of the reservable space |
@@ -1193,7 +1193,7 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, | |||
1193 | if (!next) | 1193 | if (!next) |
1194 | my_rsv->rsv_end += size; | 1194 | my_rsv->rsv_end += size; |
1195 | else { | 1195 | else { |
1196 | next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); | 1196 | next_rsv = rb_entry(next, struct ext3_reserve_window_node, rsv_node); |
1197 | 1197 | ||
1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1199 | my_rsv->rsv_end += size; | 1199 | my_rsv->rsv_end += size; |
@@ -1271,7 +1271,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1271 | } | 1271 | } |
1272 | /* | 1272 | /* |
1273 | * grp_goal is a group relative block number (if there is a goal) | 1273 | * grp_goal is a group relative block number (if there is a goal) |
1274 | * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb) | 1274 | * 0 <= grp_goal < EXT3_BLOCKS_PER_GROUP(sb) |
1275 | * first block is a filesystem wide block number | 1275 | * first block is a filesystem wide block number |
1276 | * first block is the block number of the first block in this group | 1276 | * first block is the block number of the first block in this group |
1277 | */ | 1277 | */ |
@@ -1307,10 +1307,14 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1308 | grp_goal, group, sb)) | 1308 | grp_goal, group, sb)) |
1309 | grp_goal = -1; | 1309 | grp_goal = -1; |
1310 | } else if (grp_goal > 0 && | 1310 | } else if (grp_goal >= 0) { |
1311 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1311 | int curr = my_rsv->rsv_end - |
1312 | try_to_extend_reservation(my_rsv, sb, | 1312 | (grp_goal + group_first_block) + 1; |
1313 | *count-my_rsv->rsv_end + grp_goal - 1); | 1313 | |
1314 | if (curr < *count) | ||
1315 | try_to_extend_reservation(my_rsv, sb, | ||
1316 | *count - curr); | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if ((my_rsv->rsv_start > group_last_block) || | 1319 | if ((my_rsv->rsv_start > group_last_block) || |
1316 | (my_rsv->rsv_end < group_first_block)) { | 1320 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1511,10 +1515,8 @@ retry_alloc: | |||
1511 | if (group_no >= ngroups) | 1515 | if (group_no >= ngroups) |
1512 | group_no = 0; | 1516 | group_no = 0; |
1513 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); | 1517 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); |
1514 | if (!gdp) { | 1518 | if (!gdp) |
1515 | *errp = -EIO; | 1519 | goto io_error; |
1516 | goto out; | ||
1517 | } | ||
1518 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1520 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1519 | /* | 1521 | /* |
1520 | * skip this group if the number of | 1522 | * skip this group if the number of |
@@ -1548,6 +1550,7 @@ retry_alloc: | |||
1548 | */ | 1550 | */ |
1549 | if (my_rsv) { | 1551 | if (my_rsv) { |
1550 | my_rsv = NULL; | 1552 | my_rsv = NULL; |
1553 | windowsz = 0; | ||
1551 | group_no = goal_group; | 1554 | group_no = goal_group; |
1552 | goto retry_alloc; | 1555 | goto retry_alloc; |
1553 | } | 1556 | } |
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index d0b54f30b914..665adee99b31 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -103,7 +103,7 @@ static int ext3_readdir(struct file * filp, | |||
103 | struct ext3_dir_entry_2 *de; | 103 | struct ext3_dir_entry_2 *de; |
104 | struct super_block *sb; | 104 | struct super_block *sb; |
105 | int err; | 105 | int err; |
106 | struct inode *inode = filp->f_dentry->d_inode; | 106 | struct inode *inode = filp->f_path.dentry->d_inode; |
107 | int ret = 0; | 107 | int ret = 0; |
108 | 108 | ||
109 | sb = inode->i_sb; | 109 | sb = inode->i_sb; |
@@ -122,7 +122,7 @@ static int ext3_readdir(struct file * filp, | |||
122 | * We don't set the inode dirty flag since it's not | 122 | * We don't set the inode dirty flag since it's not |
123 | * critical that it get flushed back to the disk. | 123 | * critical that it get flushed back to the disk. |
124 | */ | 124 | */ |
125 | EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL; | 125 | EXT3_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL; |
126 | } | 126 | } |
127 | #endif | 127 | #endif |
128 | stored = 0; | 128 | stored = 0; |
@@ -154,6 +154,9 @@ static int ext3_readdir(struct file * filp, | |||
154 | ext3_error (sb, "ext3_readdir", | 154 | ext3_error (sb, "ext3_readdir", |
155 | "directory #%lu contains a hole at offset %lu", | 155 | "directory #%lu contains a hole at offset %lu", |
156 | inode->i_ino, (unsigned long)filp->f_pos); | 156 | inode->i_ino, (unsigned long)filp->f_pos); |
157 | /* corrupt size? Maybe no more blocks to read */ | ||
158 | if (filp->f_pos > inode->i_blocks << 9) | ||
159 | break; | ||
157 | filp->f_pos += sb->s_blocksize - offset; | 160 | filp->f_pos += sb->s_blocksize - offset; |
158 | continue; | 161 | continue; |
159 | } | 162 | } |
@@ -399,7 +402,7 @@ static int call_filldir(struct file * filp, void * dirent, | |||
399 | { | 402 | { |
400 | struct dir_private_info *info = filp->private_data; | 403 | struct dir_private_info *info = filp->private_data; |
401 | loff_t curr_pos; | 404 | loff_t curr_pos; |
402 | struct inode *inode = filp->f_dentry->d_inode; | 405 | struct inode *inode = filp->f_path.dentry->d_inode; |
403 | struct super_block * sb; | 406 | struct super_block * sb; |
404 | int error; | 407 | int error; |
405 | 408 | ||
@@ -429,7 +432,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
429 | void * dirent, filldir_t filldir) | 432 | void * dirent, filldir_t filldir) |
430 | { | 433 | { |
431 | struct dir_private_info *info = filp->private_data; | 434 | struct dir_private_info *info = filp->private_data; |
432 | struct inode *inode = filp->f_dentry->d_inode; | 435 | struct inode *inode = filp->f_path.dentry->d_inode; |
433 | struct fname *fname; | 436 | struct fname *fname; |
434 | int ret; | 437 | int ret; |
435 | 438 | ||
diff --git a/fs/ext3/ext3_jbd.c b/fs/ext3/ext3_jbd.c new file mode 100644 index 000000000000..e1f91fd26a93 --- /dev/null +++ b/fs/ext3/ext3_jbd.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Interface between ext3 and JBD | ||
3 | */ | ||
4 | |||
5 | #include <linux/ext3_jbd.h> | ||
6 | |||
7 | int __ext3_journal_get_undo_access(const char *where, handle_t *handle, | ||
8 | struct buffer_head *bh) | ||
9 | { | ||
10 | int err = journal_get_undo_access(handle, bh); | ||
11 | if (err) | ||
12 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
13 | return err; | ||
14 | } | ||
15 | |||
16 | int __ext3_journal_get_write_access(const char *where, handle_t *handle, | ||
17 | struct buffer_head *bh) | ||
18 | { | ||
19 | int err = journal_get_write_access(handle, bh); | ||
20 | if (err) | ||
21 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
22 | return err; | ||
23 | } | ||
24 | |||
25 | int __ext3_journal_forget(const char *where, handle_t *handle, | ||
26 | struct buffer_head *bh) | ||
27 | { | ||
28 | int err = journal_forget(handle, bh); | ||
29 | if (err) | ||
30 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
31 | return err; | ||
32 | } | ||
33 | |||
34 | int __ext3_journal_revoke(const char *where, handle_t *handle, | ||
35 | unsigned long blocknr, struct buffer_head *bh) | ||
36 | { | ||
37 | int err = journal_revoke(handle, blocknr, bh); | ||
38 | if (err) | ||
39 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | int __ext3_journal_get_create_access(const char *where, | ||
44 | handle_t *handle, struct buffer_head *bh) | ||
45 | { | ||
46 | int err = journal_get_create_access(handle, bh); | ||
47 | if (err) | ||
48 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | int __ext3_journal_dirty_metadata(const char *where, | ||
53 | handle_t *handle, struct buffer_head *bh) | ||
54 | { | ||
55 | int err = journal_dirty_metadata(handle, bh); | ||
56 | if (err) | ||
57 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
58 | return err; | ||
59 | } | ||
diff --git a/fs/ext3/file.c b/fs/ext3/file.c index e96c388047e0..881f6365c41a 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c | |||
@@ -52,7 +52,7 @@ ext3_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
52 | unsigned long nr_segs, loff_t pos) | 52 | unsigned long nr_segs, loff_t pos) |
53 | { | 53 | { |
54 | struct file *file = iocb->ki_filp; | 54 | struct file *file = iocb->ki_filp; |
55 | struct inode *inode = file->f_dentry->d_inode; | 55 | struct inode *inode = file->f_path.dentry->d_inode; |
56 | ssize_t ret; | 56 | ssize_t ret; |
57 | int err; | 57 | int err; |
58 | 58 | ||
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 03ba5bcab186..beaf25f5112f 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1148,37 +1148,102 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1148 | return ext3_journal_get_write_access(handle, bh); | 1148 | return ext3_journal_get_write_access(handle, bh); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | /* | ||
1152 | * The idea of this helper function is following: | ||
1153 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1154 | * transaction must include the content of the newly allocated blocks. | ||
1155 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1156 | * 2006/10/14 SAW | ||
1157 | */ | ||
1158 | static int ext3_prepare_failure(struct file *file, struct page *page, | ||
1159 | unsigned from, unsigned to) | ||
1160 | { | ||
1161 | struct address_space *mapping; | ||
1162 | struct buffer_head *bh, *head, *next; | ||
1163 | unsigned block_start, block_end; | ||
1164 | unsigned blocksize; | ||
1165 | int ret; | ||
1166 | handle_t *handle = ext3_journal_current_handle(); | ||
1167 | |||
1168 | mapping = page->mapping; | ||
1169 | if (ext3_should_writeback_data(mapping->host)) { | ||
1170 | /* optimization: no constraints about data */ | ||
1171 | skip: | ||
1172 | return ext3_journal_stop(handle); | ||
1173 | } | ||
1174 | |||
1175 | head = page_buffers(page); | ||
1176 | blocksize = head->b_size; | ||
1177 | for ( bh = head, block_start = 0; | ||
1178 | bh != head || !block_start; | ||
1179 | block_start = block_end, bh = next) | ||
1180 | { | ||
1181 | next = bh->b_this_page; | ||
1182 | block_end = block_start + blocksize; | ||
1183 | if (block_end <= from) | ||
1184 | continue; | ||
1185 | if (block_start >= to) { | ||
1186 | block_start = to; | ||
1187 | break; | ||
1188 | } | ||
1189 | if (!buffer_mapped(bh)) | ||
1190 | /* prepare_write failed on this bh */ | ||
1191 | break; | ||
1192 | if (ext3_should_journal_data(mapping->host)) { | ||
1193 | ret = do_journal_get_write_access(handle, bh); | ||
1194 | if (ret) { | ||
1195 | ext3_journal_stop(handle); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | } | ||
1199 | /* | ||
1200 | * block_start here becomes the first block where the current iteration | ||
1201 | * of prepare_write failed. | ||
1202 | */ | ||
1203 | } | ||
1204 | if (block_start <= from) | ||
1205 | goto skip; | ||
1206 | |||
1207 | /* commit allocated and zeroed buffers */ | ||
1208 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1209 | } | ||
1210 | |||
1151 | static int ext3_prepare_write(struct file *file, struct page *page, | 1211 | static int ext3_prepare_write(struct file *file, struct page *page, |
1152 | unsigned from, unsigned to) | 1212 | unsigned from, unsigned to) |
1153 | { | 1213 | { |
1154 | struct inode *inode = page->mapping->host; | 1214 | struct inode *inode = page->mapping->host; |
1155 | int ret, needed_blocks = ext3_writepage_trans_blocks(inode); | 1215 | int ret, ret2; |
1216 | int needed_blocks = ext3_writepage_trans_blocks(inode); | ||
1156 | handle_t *handle; | 1217 | handle_t *handle; |
1157 | int retries = 0; | 1218 | int retries = 0; |
1158 | 1219 | ||
1159 | retry: | 1220 | retry: |
1160 | handle = ext3_journal_start(inode, needed_blocks); | 1221 | handle = ext3_journal_start(inode, needed_blocks); |
1161 | if (IS_ERR(handle)) { | 1222 | if (IS_ERR(handle)) |
1162 | ret = PTR_ERR(handle); | 1223 | return PTR_ERR(handle); |
1163 | goto out; | ||
1164 | } | ||
1165 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | 1224 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) |
1166 | ret = nobh_prepare_write(page, from, to, ext3_get_block); | 1225 | ret = nobh_prepare_write(page, from, to, ext3_get_block); |
1167 | else | 1226 | else |
1168 | ret = block_prepare_write(page, from, to, ext3_get_block); | 1227 | ret = block_prepare_write(page, from, to, ext3_get_block); |
1169 | if (ret) | 1228 | if (ret) |
1170 | goto prepare_write_failed; | 1229 | goto failure; |
1171 | 1230 | ||
1172 | if (ext3_should_journal_data(inode)) { | 1231 | if (ext3_should_journal_data(inode)) { |
1173 | ret = walk_page_buffers(handle, page_buffers(page), | 1232 | ret = walk_page_buffers(handle, page_buffers(page), |
1174 | from, to, NULL, do_journal_get_write_access); | 1233 | from, to, NULL, do_journal_get_write_access); |
1234 | if (ret) | ||
1235 | /* fatal error, just put the handle and return */ | ||
1236 | journal_stop(handle); | ||
1175 | } | 1237 | } |
1176 | prepare_write_failed: | 1238 | return ret; |
1177 | if (ret) | 1239 | |
1178 | ext3_journal_stop(handle); | 1240 | failure: |
1241 | ret2 = ext3_prepare_failure(file, page, from, to); | ||
1242 | if (ret2 < 0) | ||
1243 | return ret2; | ||
1179 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1244 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1180 | goto retry; | 1245 | goto retry; |
1181 | out: | 1246 | /* retry number exceeded, or other error like -EDQUOT */ |
1182 | return ret; | 1247 | return ret; |
1183 | } | 1248 | } |
1184 | 1249 | ||
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 12daa6869572..9b8090d94e6c 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -257,7 +257,7 @@ flags_err: | |||
257 | #ifdef CONFIG_COMPAT | 257 | #ifdef CONFIG_COMPAT |
258 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 258 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
259 | { | 259 | { |
260 | struct inode *inode = file->f_dentry->d_inode; | 260 | struct inode *inode = file->f_path.dentry->d_inode; |
261 | int ret; | 261 | int ret; |
262 | 262 | ||
263 | /* These are just misnamed, they actually get/put from/to user an int */ | 263 | /* These are just misnamed, they actually get/put from/to user an int */ |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 906731a20f1a..4df39c4315e1 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
552 | dir->i_sb->s_blocksize - | 552 | dir->i_sb->s_blocksize - |
553 | EXT3_DIR_REC_LEN(0)); | 553 | EXT3_DIR_REC_LEN(0)); |
554 | for (; de < top; de = ext3_next_entry(de)) { | 554 | for (; de < top; de = ext3_next_entry(de)) { |
555 | if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, | ||
556 | (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb)) | ||
557 | +((char *)de - bh->b_data))) { | ||
558 | /* On error, skip the f_pos to the next block. */ | ||
559 | dir_file->f_pos = (dir_file->f_pos | | ||
560 | (dir->i_sb->s_blocksize - 1)) + 1; | ||
561 | brelse (bh); | ||
562 | return count; | ||
563 | } | ||
555 | ext3fs_dirhash(de->name, de->name_len, hinfo); | 564 | ext3fs_dirhash(de->name, de->name_len, hinfo); |
556 | if ((hinfo->hash < start_hash) || | 565 | if ((hinfo->hash < start_hash) || |
557 | ((hinfo->hash == start_hash) && | 566 | ((hinfo->hash == start_hash) && |
@@ -593,7 +602,7 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
593 | 602 | ||
594 | dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, | 603 | dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, |
595 | start_minor_hash)); | 604 | start_minor_hash)); |
596 | dir = dir_file->f_dentry->d_inode; | 605 | dir = dir_file->f_path.dentry->d_inode; |
597 | if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) { | 606 | if (!(EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) { |
598 | hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; | 607 | hinfo.hash_version = EXT3_SB(dir->i_sb)->s_def_hash_version; |
599 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; | 608 | hinfo.seed = EXT3_SB(dir->i_sb)->s_hash_seed; |
@@ -604,7 +613,7 @@ int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
604 | } | 613 | } |
605 | hinfo.hash = start_hash; | 614 | hinfo.hash = start_hash; |
606 | hinfo.minor_hash = 0; | 615 | hinfo.minor_hash = 0; |
607 | frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); | 616 | frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err); |
608 | if (!frame) | 617 | if (!frame) |
609 | return err; | 618 | return err; |
610 | 619 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index afc2d4f42d77..b34886734a44 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -436,7 +436,7 @@ static void ext3_put_super (struct super_block * sb) | |||
436 | return; | 436 | return; |
437 | } | 437 | } |
438 | 438 | ||
439 | static kmem_cache_t *ext3_inode_cachep; | 439 | static struct kmem_cache *ext3_inode_cachep; |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Called inside transaction, so use GFP_NOFS | 442 | * Called inside transaction, so use GFP_NOFS |
@@ -445,7 +445,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) | |||
445 | { | 445 | { |
446 | struct ext3_inode_info *ei; | 446 | struct ext3_inode_info *ei; |
447 | 447 | ||
448 | ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS); | 448 | ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); |
449 | if (!ei) | 449 | if (!ei) |
450 | return NULL; | 450 | return NULL; |
451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
@@ -462,7 +462,7 @@ static void ext3_destroy_inode(struct inode *inode) | |||
462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); | 462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); |
463 | } | 463 | } |
464 | 464 | ||
465 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 465 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
466 | { | 466 | { |
467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
468 | 468 | ||
@@ -1264,6 +1264,12 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1264 | return; | 1264 | return; |
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | if (bdev_read_only(sb->s_bdev)) { | ||
1268 | printk(KERN_ERR "EXT3-fs: write access " | ||
1269 | "unavailable, skipping orphan cleanup.\n"); | ||
1270 | return; | ||
1271 | } | ||
1272 | |||
1267 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { | 1273 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { |
1268 | if (es->s_last_orphan) | 1274 | if (es->s_last_orphan) |
1269 | jbd_debug(1, "Errors on filesystem, " | 1275 | jbd_debug(1, "Errors on filesystem, " |
@@ -1341,8 +1347,6 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1341 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ | 1347 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ |
1342 | } | 1348 | } |
1343 | 1349 | ||
1344 | #define log2(n) ffz(~(n)) | ||
1345 | |||
1346 | /* | 1350 | /* |
1347 | * Maximal file size. There is a direct, and {,double-,triple-}indirect | 1351 | * Maximal file size. There is a direct, and {,double-,triple-}indirect |
1348 | * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. | 1352 | * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. |
@@ -1591,8 +1595,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1591 | sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc); | 1595 | sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc); |
1592 | sbi->s_sbh = bh; | 1596 | sbi->s_sbh = bh; |
1593 | sbi->s_mount_state = le16_to_cpu(es->s_state); | 1597 | sbi->s_mount_state = le16_to_cpu(es->s_state); |
1594 | sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb)); | 1598 | sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb)); |
1595 | sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb)); | 1599 | sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb)); |
1596 | for (i=0; i < 4; i++) | 1600 | for (i=0; i < 4; i++) |
1597 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | 1601 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); |
1598 | sbi->s_def_hash_version = es->s_def_hash_version; | 1602 | sbi->s_def_hash_version = es->s_def_hash_version; |
@@ -2387,6 +2391,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2387 | struct ext3_super_block *es = sbi->s_es; | 2391 | struct ext3_super_block *es = sbi->s_es; |
2388 | ext3_fsblk_t overhead; | 2392 | ext3_fsblk_t overhead; |
2389 | int i; | 2393 | int i; |
2394 | u64 fsid; | ||
2390 | 2395 | ||
2391 | if (test_opt (sb, MINIX_DF)) | 2396 | if (test_opt (sb, MINIX_DF)) |
2392 | overhead = 0; | 2397 | overhead = 0; |
@@ -2433,6 +2438,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2433 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2438 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2434 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2439 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2435 | buf->f_namelen = EXT3_NAME_LEN; | 2440 | buf->f_namelen = EXT3_NAME_LEN; |
2441 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
2442 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
2443 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
2444 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
2436 | return 0; | 2445 | return 0; |
2437 | } | 2446 | } |
2438 | 2447 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index f86f2482f01d..99857a400f4b 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -459,14 +459,11 @@ static void ext3_xattr_update_super_block(handle_t *handle, | |||
459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) | 459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | lock_super(sb); | ||
463 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { | 462 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { |
464 | EXT3_SB(sb)->s_es->s_feature_compat |= | 463 | EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR); |
465 | cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); | ||
466 | sb->s_dirt = 1; | 464 | sb->s_dirt = 1; |
467 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); | 465 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); |
468 | } | 466 | } |
469 | unlock_super(sb); | ||
470 | } | 467 | } |
471 | 468 | ||
472 | /* | 469 | /* |
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index a6acb96ebeb9..ae6e7e502ac9 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile | |||
@@ -5,7 +5,8 @@ | |||
5 | obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o | 5 | obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o |
6 | 6 | ||
7 | ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ |
9 | ext4_jbd2.o | ||
9 | 10 | ||
10 | ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 11 | ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
11 | ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o | 12 | ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 5d45582f9517..c4dd1103ccf1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -165,7 +165,7 @@ restart: | |||
165 | 165 | ||
166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
167 | while (n) { | 167 | while (n) { |
168 | rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); | 168 | rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); |
169 | if (verbose) | 169 | if (verbose) |
170 | printk("reservation window 0x%p " | 170 | printk("reservation window 0x%p " |
171 | "start: %llu, end: %llu\n", | 171 | "start: %llu, end: %llu\n", |
@@ -747,7 +747,7 @@ find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, | |||
747 | here = 0; | 747 | here = 0; |
748 | 748 | ||
749 | p = ((char *)bh->b_data) + (here >> 3); | 749 | p = ((char *)bh->b_data) + (here >> 3); |
750 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 750 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
751 | next = (r - ((char *)bh->b_data)) << 3; | 751 | next = (r - ((char *)bh->b_data)) << 3; |
752 | 752 | ||
753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) | 753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) |
@@ -966,7 +966,7 @@ static int find_next_reservable_window( | |||
966 | 966 | ||
967 | prev = rsv; | 967 | prev = rsv; |
968 | next = rb_next(&rsv->rsv_node); | 968 | next = rb_next(&rsv->rsv_node); |
969 | rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node); | 969 | rsv = rb_entry(next,struct ext4_reserve_window_node,rsv_node); |
970 | 970 | ||
971 | /* | 971 | /* |
972 | * Reached the last reservation, we can just append to the | 972 | * Reached the last reservation, we can just append to the |
@@ -1165,7 +1165,7 @@ retry: | |||
1165 | * check if the first free block is within the | 1165 | * check if the first free block is within the |
1166 | * free space we just reserved | 1166 | * free space we just reserved |
1167 | */ | 1167 | */ |
1168 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1168 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1169 | return 0; /* success */ | 1169 | return 0; /* success */ |
1170 | /* | 1170 | /* |
1171 | * if the first free bit we found is out of the reservable space | 1171 | * if the first free bit we found is out of the reservable space |
@@ -1210,7 +1210,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv, | |||
1210 | if (!next) | 1210 | if (!next) |
1211 | my_rsv->rsv_end += size; | 1211 | my_rsv->rsv_end += size; |
1212 | else { | 1212 | else { |
1213 | next_rsv = list_entry(next, struct ext4_reserve_window_node, rsv_node); | 1213 | next_rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node); |
1214 | 1214 | ||
1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1216 | my_rsv->rsv_end += size; | 1216 | my_rsv->rsv_end += size; |
@@ -1288,7 +1288,7 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1288 | } | 1288 | } |
1289 | /* | 1289 | /* |
1290 | * grp_goal is a group relative block number (if there is a goal) | 1290 | * grp_goal is a group relative block number (if there is a goal) |
1291 | * 0 < grp_goal < EXT4_BLOCKS_PER_GROUP(sb) | 1291 | * 0 <= grp_goal < EXT4_BLOCKS_PER_GROUP(sb) |
1292 | * first block is a filesystem wide block number | 1292 | * first block is a filesystem wide block number |
1293 | * first block is the block number of the first block in this group | 1293 | * first block is the block number of the first block in this group |
1294 | */ | 1294 | */ |
@@ -1324,10 +1324,14 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1325 | grp_goal, group, sb)) | 1325 | grp_goal, group, sb)) |
1326 | grp_goal = -1; | 1326 | grp_goal = -1; |
1327 | } else if (grp_goal > 0 && | 1327 | } else if (grp_goal >= 0) { |
1328 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1328 | int curr = my_rsv->rsv_end - |
1329 | try_to_extend_reservation(my_rsv, sb, | 1329 | (grp_goal + group_first_block) + 1; |
1330 | *count-my_rsv->rsv_end + grp_goal - 1); | 1330 | |
1331 | if (curr < *count) | ||
1332 | try_to_extend_reservation(my_rsv, sb, | ||
1333 | *count - curr); | ||
1334 | } | ||
1331 | 1335 | ||
1332 | if ((my_rsv->rsv_start > group_last_block) || | 1336 | if ((my_rsv->rsv_start > group_last_block) || |
1333 | (my_rsv->rsv_end < group_first_block)) { | 1337 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1525,10 +1529,8 @@ retry_alloc: | |||
1525 | if (group_no >= ngroups) | 1529 | if (group_no >= ngroups) |
1526 | group_no = 0; | 1530 | group_no = 0; |
1527 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); | 1531 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); |
1528 | if (!gdp) { | 1532 | if (!gdp) |
1529 | *errp = -EIO; | 1533 | goto io_error; |
1530 | goto out; | ||
1531 | } | ||
1532 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1534 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1533 | /* | 1535 | /* |
1534 | * skip this group if the number of | 1536 | * skip this group if the number of |
@@ -1562,6 +1564,7 @@ retry_alloc: | |||
1562 | */ | 1564 | */ |
1563 | if (my_rsv) { | 1565 | if (my_rsv) { |
1564 | my_rsv = NULL; | 1566 | my_rsv = NULL; |
1567 | windowsz = 0; | ||
1565 | group_no = goal_group; | 1568 | group_no = goal_group; |
1566 | goto retry_alloc; | 1569 | goto retry_alloc; |
1567 | } | 1570 | } |
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index f8595787a70e..da80368b66f0 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -103,7 +103,7 @@ static int ext4_readdir(struct file * filp, | |||
103 | struct ext4_dir_entry_2 *de; | 103 | struct ext4_dir_entry_2 *de; |
104 | struct super_block *sb; | 104 | struct super_block *sb; |
105 | int err; | 105 | int err; |
106 | struct inode *inode = filp->f_dentry->d_inode; | 106 | struct inode *inode = filp->f_path.dentry->d_inode; |
107 | int ret = 0; | 107 | int ret = 0; |
108 | 108 | ||
109 | sb = inode->i_sb; | 109 | sb = inode->i_sb; |
@@ -122,7 +122,7 @@ static int ext4_readdir(struct file * filp, | |||
122 | * We don't set the inode dirty flag since it's not | 122 | * We don't set the inode dirty flag since it's not |
123 | * critical that it get flushed back to the disk. | 123 | * critical that it get flushed back to the disk. |
124 | */ | 124 | */ |
125 | EXT4_I(filp->f_dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; | 125 | EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; |
126 | } | 126 | } |
127 | #endif | 127 | #endif |
128 | stored = 0; | 128 | stored = 0; |
@@ -153,6 +153,9 @@ static int ext4_readdir(struct file * filp, | |||
153 | ext4_error (sb, "ext4_readdir", | 153 | ext4_error (sb, "ext4_readdir", |
154 | "directory #%lu contains a hole at offset %lu", | 154 | "directory #%lu contains a hole at offset %lu", |
155 | inode->i_ino, (unsigned long)filp->f_pos); | 155 | inode->i_ino, (unsigned long)filp->f_pos); |
156 | /* corrupt size? Maybe no more blocks to read */ | ||
157 | if (filp->f_pos > inode->i_blocks << 9) | ||
158 | break; | ||
156 | filp->f_pos += sb->s_blocksize - offset; | 159 | filp->f_pos += sb->s_blocksize - offset; |
157 | continue; | 160 | continue; |
158 | } | 161 | } |
@@ -399,7 +402,7 @@ static int call_filldir(struct file * filp, void * dirent, | |||
399 | { | 402 | { |
400 | struct dir_private_info *info = filp->private_data; | 403 | struct dir_private_info *info = filp->private_data; |
401 | loff_t curr_pos; | 404 | loff_t curr_pos; |
402 | struct inode *inode = filp->f_dentry->d_inode; | 405 | struct inode *inode = filp->f_path.dentry->d_inode; |
403 | struct super_block * sb; | 406 | struct super_block * sb; |
404 | int error; | 407 | int error; |
405 | 408 | ||
@@ -429,7 +432,7 @@ static int ext4_dx_readdir(struct file * filp, | |||
429 | void * dirent, filldir_t filldir) | 432 | void * dirent, filldir_t filldir) |
430 | { | 433 | { |
431 | struct dir_private_info *info = filp->private_data; | 434 | struct dir_private_info *info = filp->private_data; |
432 | struct inode *inode = filp->f_dentry->d_inode; | 435 | struct inode *inode = filp->f_path.dentry->d_inode; |
433 | struct fname *fname; | 436 | struct fname *fname; |
434 | int ret; | 437 | int ret; |
435 | 438 | ||
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c new file mode 100644 index 000000000000..d6afe4e27340 --- /dev/null +++ b/fs/ext4/ext4_jbd2.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Interface between ext4 and JBD | ||
3 | */ | ||
4 | |||
5 | #include <linux/ext4_jbd2.h> | ||
6 | |||
7 | int __ext4_journal_get_undo_access(const char *where, handle_t *handle, | ||
8 | struct buffer_head *bh) | ||
9 | { | ||
10 | int err = jbd2_journal_get_undo_access(handle, bh); | ||
11 | if (err) | ||
12 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
13 | return err; | ||
14 | } | ||
15 | |||
16 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, | ||
17 | struct buffer_head *bh) | ||
18 | { | ||
19 | int err = jbd2_journal_get_write_access(handle, bh); | ||
20 | if (err) | ||
21 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
22 | return err; | ||
23 | } | ||
24 | |||
25 | int __ext4_journal_forget(const char *where, handle_t *handle, | ||
26 | struct buffer_head *bh) | ||
27 | { | ||
28 | int err = jbd2_journal_forget(handle, bh); | ||
29 | if (err) | ||
30 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
31 | return err; | ||
32 | } | ||
33 | |||
34 | int __ext4_journal_revoke(const char *where, handle_t *handle, | ||
35 | ext4_fsblk_t blocknr, struct buffer_head *bh) | ||
36 | { | ||
37 | int err = jbd2_journal_revoke(handle, blocknr, bh); | ||
38 | if (err) | ||
39 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | int __ext4_journal_get_create_access(const char *where, | ||
44 | handle_t *handle, struct buffer_head *bh) | ||
45 | { | ||
46 | int err = jbd2_journal_get_create_access(handle, bh); | ||
47 | if (err) | ||
48 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | int __ext4_journal_dirty_metadata(const char *where, | ||
53 | handle_t *handle, struct buffer_head *bh) | ||
54 | { | ||
55 | int err = jbd2_journal_dirty_metadata(handle, bh); | ||
56 | if (err) | ||
57 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
58 | return err; | ||
59 | } | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2608dce18f3e..dc2724fa7622 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -48,7 +48,7 @@ | |||
48 | * ext_pblock: | 48 | * ext_pblock: |
49 | * combine low and high parts of physical block number into ext4_fsblk_t | 49 | * combine low and high parts of physical block number into ext4_fsblk_t |
50 | */ | 50 | */ |
51 | static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | 51 | static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) |
52 | { | 52 | { |
53 | ext4_fsblk_t block; | 53 | ext4_fsblk_t block; |
54 | 54 | ||
@@ -61,7 +61,7 @@ static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | |||
61 | * idx_pblock: | 61 | * idx_pblock: |
62 | * combine low and high parts of a leaf physical block number into ext4_fsblk_t | 62 | * combine low and high parts of a leaf physical block number into ext4_fsblk_t |
63 | */ | 63 | */ |
64 | static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | 64 | static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) |
65 | { | 65 | { |
66 | ext4_fsblk_t block; | 66 | ext4_fsblk_t block; |
67 | 67 | ||
@@ -75,7 +75,7 @@ static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | |||
75 | * stores a large physical block number into an extent struct, | 75 | * stores a large physical block number into an extent struct, |
76 | * breaking it into parts | 76 | * breaking it into parts |
77 | */ | 77 | */ |
78 | static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) | 78 | static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) |
79 | { | 79 | { |
80 | ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 80 | ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
@@ -86,7 +86,7 @@ static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb | |||
86 | * stores a large physical block number into an index struct, | 86 | * stores a large physical block number into an index struct, |
87 | * breaking it into parts | 87 | * breaking it into parts |
88 | */ | 88 | */ |
89 | static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | 89 | static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) |
90 | { | 90 | { |
91 | ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 91 | ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
@@ -186,7 +186,8 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
186 | depth = path->p_depth; | 186 | depth = path->p_depth; |
187 | 187 | ||
188 | /* try to predict block placement */ | 188 | /* try to predict block placement */ |
189 | if ((ex = path[depth].p_ext)) | 189 | ex = path[depth].p_ext; |
190 | if (ex) | ||
190 | return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); | 191 | return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); |
191 | 192 | ||
192 | /* it looks like index is empty; | 193 | /* it looks like index is empty; |
@@ -215,7 +216,7 @@ ext4_ext_new_block(handle_t *handle, struct inode *inode, | |||
215 | return newblock; | 216 | return newblock; |
216 | } | 217 | } |
217 | 218 | ||
218 | static inline int ext4_ext_space_block(struct inode *inode) | 219 | static int ext4_ext_space_block(struct inode *inode) |
219 | { | 220 | { |
220 | int size; | 221 | int size; |
221 | 222 | ||
@@ -228,7 +229,7 @@ static inline int ext4_ext_space_block(struct inode *inode) | |||
228 | return size; | 229 | return size; |
229 | } | 230 | } |
230 | 231 | ||
231 | static inline int ext4_ext_space_block_idx(struct inode *inode) | 232 | static int ext4_ext_space_block_idx(struct inode *inode) |
232 | { | 233 | { |
233 | int size; | 234 | int size; |
234 | 235 | ||
@@ -241,7 +242,7 @@ static inline int ext4_ext_space_block_idx(struct inode *inode) | |||
241 | return size; | 242 | return size; |
242 | } | 243 | } |
243 | 244 | ||
244 | static inline int ext4_ext_space_root(struct inode *inode) | 245 | static int ext4_ext_space_root(struct inode *inode) |
245 | { | 246 | { |
246 | int size; | 247 | int size; |
247 | 248 | ||
@@ -255,7 +256,7 @@ static inline int ext4_ext_space_root(struct inode *inode) | |||
255 | return size; | 256 | return size; |
256 | } | 257 | } |
257 | 258 | ||
258 | static inline int ext4_ext_space_root_idx(struct inode *inode) | 259 | static int ext4_ext_space_root_idx(struct inode *inode) |
259 | { | 260 | { |
260 | int size; | 261 | int size; |
261 | 262 | ||
@@ -476,13 +477,12 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
476 | 477 | ||
477 | /* account possible depth increase */ | 478 | /* account possible depth increase */ |
478 | if (!path) { | 479 | if (!path) { |
479 | path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 2), | 480 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2), |
480 | GFP_NOFS); | 481 | GFP_NOFS); |
481 | if (!path) | 482 | if (!path) |
482 | return ERR_PTR(-ENOMEM); | 483 | return ERR_PTR(-ENOMEM); |
483 | alloc = 1; | 484 | alloc = 1; |
484 | } | 485 | } |
485 | memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); | ||
486 | path[0].p_hdr = eh; | 486 | path[0].p_hdr = eh; |
487 | 487 | ||
488 | /* walk through the tree */ | 488 | /* walk through the tree */ |
@@ -543,7 +543,8 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
543 | struct ext4_extent_idx *ix; | 543 | struct ext4_extent_idx *ix; |
544 | int len, err; | 544 | int len, err; |
545 | 545 | ||
546 | if ((err = ext4_ext_get_access(handle, inode, curp))) | 546 | err = ext4_ext_get_access(handle, inode, curp); |
547 | if (err) | ||
547 | return err; | 548 | return err; |
548 | 549 | ||
549 | BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); | 550 | BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); |
@@ -641,10 +642,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
641 | * We need this to handle errors and free blocks | 642 | * We need this to handle errors and free blocks |
642 | * upon them. | 643 | * upon them. |
643 | */ | 644 | */ |
644 | ablocks = kmalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); | 645 | ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); |
645 | if (!ablocks) | 646 | if (!ablocks) |
646 | return -ENOMEM; | 647 | return -ENOMEM; |
647 | memset(ablocks, 0, sizeof(ext4_fsblk_t) * depth); | ||
648 | 648 | ||
649 | /* allocate all needed blocks */ | 649 | /* allocate all needed blocks */ |
650 | ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); | 650 | ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); |
@@ -665,7 +665,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
665 | } | 665 | } |
666 | lock_buffer(bh); | 666 | lock_buffer(bh); |
667 | 667 | ||
668 | if ((err = ext4_journal_get_create_access(handle, bh))) | 668 | err = ext4_journal_get_create_access(handle, bh); |
669 | if (err) | ||
669 | goto cleanup; | 670 | goto cleanup; |
670 | 671 | ||
671 | neh = ext_block_hdr(bh); | 672 | neh = ext_block_hdr(bh); |
@@ -702,18 +703,21 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
702 | set_buffer_uptodate(bh); | 703 | set_buffer_uptodate(bh); |
703 | unlock_buffer(bh); | 704 | unlock_buffer(bh); |
704 | 705 | ||
705 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 706 | err = ext4_journal_dirty_metadata(handle, bh); |
707 | if (err) | ||
706 | goto cleanup; | 708 | goto cleanup; |
707 | brelse(bh); | 709 | brelse(bh); |
708 | bh = NULL; | 710 | bh = NULL; |
709 | 711 | ||
710 | /* correct old leaf */ | 712 | /* correct old leaf */ |
711 | if (m) { | 713 | if (m) { |
712 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 714 | err = ext4_ext_get_access(handle, inode, path + depth); |
715 | if (err) | ||
713 | goto cleanup; | 716 | goto cleanup; |
714 | path[depth].p_hdr->eh_entries = | 717 | path[depth].p_hdr->eh_entries = |
715 | cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); | 718 | cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); |
716 | if ((err = ext4_ext_dirty(handle, inode, path + depth))) | 719 | err = ext4_ext_dirty(handle, inode, path + depth); |
720 | if (err) | ||
717 | goto cleanup; | 721 | goto cleanup; |
718 | 722 | ||
719 | } | 723 | } |
@@ -736,7 +740,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
736 | } | 740 | } |
737 | lock_buffer(bh); | 741 | lock_buffer(bh); |
738 | 742 | ||
739 | if ((err = ext4_journal_get_create_access(handle, bh))) | 743 | err = ext4_journal_get_create_access(handle, bh); |
744 | if (err) | ||
740 | goto cleanup; | 745 | goto cleanup; |
741 | 746 | ||
742 | neh = ext_block_hdr(bh); | 747 | neh = ext_block_hdr(bh); |
@@ -780,7 +785,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
780 | set_buffer_uptodate(bh); | 785 | set_buffer_uptodate(bh); |
781 | unlock_buffer(bh); | 786 | unlock_buffer(bh); |
782 | 787 | ||
783 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 788 | err = ext4_journal_dirty_metadata(handle, bh); |
789 | if (err) | ||
784 | goto cleanup; | 790 | goto cleanup; |
785 | brelse(bh); | 791 | brelse(bh); |
786 | bh = NULL; | 792 | bh = NULL; |
@@ -800,9 +806,6 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
800 | } | 806 | } |
801 | 807 | ||
802 | /* insert new index */ | 808 | /* insert new index */ |
803 | if (err) | ||
804 | goto cleanup; | ||
805 | |||
806 | err = ext4_ext_insert_index(handle, inode, path + at, | 809 | err = ext4_ext_insert_index(handle, inode, path + at, |
807 | le32_to_cpu(border), newblock); | 810 | le32_to_cpu(border), newblock); |
808 | 811 | ||
@@ -857,7 +860,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
857 | } | 860 | } |
858 | lock_buffer(bh); | 861 | lock_buffer(bh); |
859 | 862 | ||
860 | if ((err = ext4_journal_get_create_access(handle, bh))) { | 863 | err = ext4_journal_get_create_access(handle, bh); |
864 | if (err) { | ||
861 | unlock_buffer(bh); | 865 | unlock_buffer(bh); |
862 | goto out; | 866 | goto out; |
863 | } | 867 | } |
@@ -877,11 +881,13 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
877 | set_buffer_uptodate(bh); | 881 | set_buffer_uptodate(bh); |
878 | unlock_buffer(bh); | 882 | unlock_buffer(bh); |
879 | 883 | ||
880 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 884 | err = ext4_journal_dirty_metadata(handle, bh); |
885 | if (err) | ||
881 | goto out; | 886 | goto out; |
882 | 887 | ||
883 | /* create index in new top-level index: num,max,pointer */ | 888 | /* create index in new top-level index: num,max,pointer */ |
884 | if ((err = ext4_ext_get_access(handle, inode, curp))) | 889 | err = ext4_ext_get_access(handle, inode, curp); |
890 | if (err) | ||
885 | goto out; | 891 | goto out; |
886 | 892 | ||
887 | curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; | 893 | curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; |
@@ -1073,27 +1079,31 @@ int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, | |||
1073 | */ | 1079 | */ |
1074 | k = depth - 1; | 1080 | k = depth - 1; |
1075 | border = path[depth].p_ext->ee_block; | 1081 | border = path[depth].p_ext->ee_block; |
1076 | if ((err = ext4_ext_get_access(handle, inode, path + k))) | 1082 | err = ext4_ext_get_access(handle, inode, path + k); |
1083 | if (err) | ||
1077 | return err; | 1084 | return err; |
1078 | path[k].p_idx->ei_block = border; | 1085 | path[k].p_idx->ei_block = border; |
1079 | if ((err = ext4_ext_dirty(handle, inode, path + k))) | 1086 | err = ext4_ext_dirty(handle, inode, path + k); |
1087 | if (err) | ||
1080 | return err; | 1088 | return err; |
1081 | 1089 | ||
1082 | while (k--) { | 1090 | while (k--) { |
1083 | /* change all left-side indexes */ | 1091 | /* change all left-side indexes */ |
1084 | if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) | 1092 | if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) |
1085 | break; | 1093 | break; |
1086 | if ((err = ext4_ext_get_access(handle, inode, path + k))) | 1094 | err = ext4_ext_get_access(handle, inode, path + k); |
1095 | if (err) | ||
1087 | break; | 1096 | break; |
1088 | path[k].p_idx->ei_block = border; | 1097 | path[k].p_idx->ei_block = border; |
1089 | if ((err = ext4_ext_dirty(handle, inode, path + k))) | 1098 | err = ext4_ext_dirty(handle, inode, path + k); |
1099 | if (err) | ||
1090 | break; | 1100 | break; |
1091 | } | 1101 | } |
1092 | 1102 | ||
1093 | return err; | 1103 | return err; |
1094 | } | 1104 | } |
1095 | 1105 | ||
1096 | static int inline | 1106 | static int |
1097 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | 1107 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, |
1098 | struct ext4_extent *ex2) | 1108 | struct ext4_extent *ex2) |
1099 | { | 1109 | { |
@@ -1145,7 +1155,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1145 | le16_to_cpu(newext->ee_len), | 1155 | le16_to_cpu(newext->ee_len), |
1146 | le32_to_cpu(ex->ee_block), | 1156 | le32_to_cpu(ex->ee_block), |
1147 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 1157 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); |
1148 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 1158 | err = ext4_ext_get_access(handle, inode, path + depth); |
1159 | if (err) | ||
1149 | return err; | 1160 | return err; |
1150 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) | 1161 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) |
1151 | + le16_to_cpu(newext->ee_len)); | 1162 | + le16_to_cpu(newext->ee_len)); |
@@ -1195,7 +1206,8 @@ repeat: | |||
1195 | has_space: | 1206 | has_space: |
1196 | nearex = path[depth].p_ext; | 1207 | nearex = path[depth].p_ext; |
1197 | 1208 | ||
1198 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 1209 | err = ext4_ext_get_access(handle, inode, path + depth); |
1210 | if (err) | ||
1199 | goto cleanup; | 1211 | goto cleanup; |
1200 | 1212 | ||
1201 | if (!nearex) { | 1213 | if (!nearex) { |
@@ -1383,7 +1395,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
1383 | return err; | 1395 | return err; |
1384 | } | 1396 | } |
1385 | 1397 | ||
1386 | static inline void | 1398 | static void |
1387 | ext4_ext_put_in_cache(struct inode *inode, __u32 block, | 1399 | ext4_ext_put_in_cache(struct inode *inode, __u32 block, |
1388 | __u32 len, __u32 start, int type) | 1400 | __u32 len, __u32 start, int type) |
1389 | { | 1401 | { |
@@ -1401,7 +1413,7 @@ ext4_ext_put_in_cache(struct inode *inode, __u32 block, | |||
1401 | * calculate boundaries of the gap that the requested block fits into | 1413 | * calculate boundaries of the gap that the requested block fits into |
1402 | * and cache this gap | 1414 | * and cache this gap |
1403 | */ | 1415 | */ |
1404 | static inline void | 1416 | static void |
1405 | ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | 1417 | ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, |
1406 | unsigned long block) | 1418 | unsigned long block) |
1407 | { | 1419 | { |
@@ -1442,7 +1454,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
1442 | ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); | 1454 | ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); |
1443 | } | 1455 | } |
1444 | 1456 | ||
1445 | static inline int | 1457 | static int |
1446 | ext4_ext_in_cache(struct inode *inode, unsigned long block, | 1458 | ext4_ext_in_cache(struct inode *inode, unsigned long block, |
1447 | struct ext4_extent *ex) | 1459 | struct ext4_extent *ex) |
1448 | { | 1460 | { |
@@ -1489,10 +1501,12 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1489 | path--; | 1501 | path--; |
1490 | leaf = idx_pblock(path->p_idx); | 1502 | leaf = idx_pblock(path->p_idx); |
1491 | BUG_ON(path->p_hdr->eh_entries == 0); | 1503 | BUG_ON(path->p_hdr->eh_entries == 0); |
1492 | if ((err = ext4_ext_get_access(handle, inode, path))) | 1504 | err = ext4_ext_get_access(handle, inode, path); |
1505 | if (err) | ||
1493 | return err; | 1506 | return err; |
1494 | path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); | 1507 | path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); |
1495 | if ((err = ext4_ext_dirty(handle, inode, path))) | 1508 | err = ext4_ext_dirty(handle, inode, path); |
1509 | if (err) | ||
1496 | return err; | 1510 | return err; |
1497 | ext_debug("index is empty, remove it, free block %llu\n", leaf); | 1511 | ext_debug("index is empty, remove it, free block %llu\n", leaf); |
1498 | bh = sb_find_get_block(inode->i_sb, leaf); | 1512 | bh = sb_find_get_block(inode->i_sb, leaf); |
@@ -1509,7 +1523,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1509 | * the caller should calculate credits under truncate_mutex and | 1523 | * the caller should calculate credits under truncate_mutex and |
1510 | * pass the actual path. | 1524 | * pass the actual path. |
1511 | */ | 1525 | */ |
1512 | int inline ext4_ext_calc_credits_for_insert(struct inode *inode, | 1526 | int ext4_ext_calc_credits_for_insert(struct inode *inode, |
1513 | struct ext4_ext_path *path) | 1527 | struct ext4_ext_path *path) |
1514 | { | 1528 | { |
1515 | int depth, needed; | 1529 | int depth, needed; |
@@ -1534,16 +1548,17 @@ int inline ext4_ext_calc_credits_for_insert(struct inode *inode, | |||
1534 | 1548 | ||
1535 | /* | 1549 | /* |
1536 | * tree can be full, so it would need to grow in depth: | 1550 | * tree can be full, so it would need to grow in depth: |
1537 | * allocation + old root + new root | 1551 | * we need one credit to modify old root, credits for |
1552 | * new root will be added in split accounting | ||
1538 | */ | 1553 | */ |
1539 | needed += 2 + 1 + 1; | 1554 | needed += 1; |
1540 | 1555 | ||
1541 | /* | 1556 | /* |
1542 | * Index split can happen, we would need: | 1557 | * Index split can happen, we would need: |
1543 | * allocate intermediate indexes (bitmap + group) | 1558 | * allocate intermediate indexes (bitmap + group) |
1544 | * + change two blocks at each level, but root (already included) | 1559 | * + change two blocks at each level, but root (already included) |
1545 | */ | 1560 | */ |
1546 | needed = (depth * 2) + (depth * 2); | 1561 | needed += (depth * 2) + (depth * 2); |
1547 | 1562 | ||
1548 | /* any allocation modifies superblock */ | 1563 | /* any allocation modifies superblock */ |
1549 | needed += 1; | 1564 | needed += 1; |
@@ -1718,7 +1733,7 @@ out: | |||
1718 | * ext4_ext_more_to_rm: | 1733 | * ext4_ext_more_to_rm: |
1719 | * returns 1 if current index has to be freed (even partial) | 1734 | * returns 1 if current index has to be freed (even partial) |
1720 | */ | 1735 | */ |
1721 | static int inline | 1736 | static int |
1722 | ext4_ext_more_to_rm(struct ext4_ext_path *path) | 1737 | ext4_ext_more_to_rm(struct ext4_ext_path *path) |
1723 | { | 1738 | { |
1724 | BUG_ON(path->p_idx == NULL); | 1739 | BUG_ON(path->p_idx == NULL); |
@@ -1756,12 +1771,11 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
1756 | * We start scanning from right side, freeing all the blocks | 1771 | * We start scanning from right side, freeing all the blocks |
1757 | * after i_size and walking into the tree depth-wise. | 1772 | * after i_size and walking into the tree depth-wise. |
1758 | */ | 1773 | */ |
1759 | path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); | 1774 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); |
1760 | if (path == NULL) { | 1775 | if (path == NULL) { |
1761 | ext4_journal_stop(handle); | 1776 | ext4_journal_stop(handle); |
1762 | return -ENOMEM; | 1777 | return -ENOMEM; |
1763 | } | 1778 | } |
1764 | memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); | ||
1765 | path[0].p_hdr = ext_inode_hdr(inode); | 1779 | path[0].p_hdr = ext_inode_hdr(inode); |
1766 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { | 1780 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { |
1767 | err = -EIO; | 1781 | err = -EIO; |
@@ -1932,7 +1946,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
1932 | mutex_lock(&EXT4_I(inode)->truncate_mutex); | 1946 | mutex_lock(&EXT4_I(inode)->truncate_mutex); |
1933 | 1947 | ||
1934 | /* check in cache */ | 1948 | /* check in cache */ |
1935 | if ((goal = ext4_ext_in_cache(inode, iblock, &newex))) { | 1949 | goal = ext4_ext_in_cache(inode, iblock, &newex); |
1950 | if (goal) { | ||
1936 | if (goal == EXT4_EXT_CACHE_GAP) { | 1951 | if (goal == EXT4_EXT_CACHE_GAP) { |
1937 | if (!create) { | 1952 | if (!create) { |
1938 | /* block isn't allocated yet and | 1953 | /* block isn't allocated yet and |
@@ -1971,7 +1986,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
1971 | */ | 1986 | */ |
1972 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 1987 | BUG_ON(path[depth].p_ext == NULL && depth != 0); |
1973 | 1988 | ||
1974 | if ((ex = path[depth].p_ext)) { | 1989 | ex = path[depth].p_ext; |
1990 | if (ex) { | ||
1975 | unsigned long ee_block = le32_to_cpu(ex->ee_block); | 1991 | unsigned long ee_block = le32_to_cpu(ex->ee_block); |
1976 | ext4_fsblk_t ee_start = ext_pblock(ex); | 1992 | ext4_fsblk_t ee_start = ext_pblock(ex); |
1977 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | 1993 | unsigned short ee_len = le16_to_cpu(ex->ee_len); |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 0b622c0624b7..3bbc24b58785 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -52,7 +52,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
52 | unsigned long nr_segs, loff_t pos) | 52 | unsigned long nr_segs, loff_t pos) |
53 | { | 53 | { |
54 | struct file *file = iocb->ki_filp; | 54 | struct file *file = iocb->ki_filp; |
55 | struct inode *inode = file->f_dentry->d_inode; | 55 | struct inode *inode = file->f_path.dentry->d_inode; |
56 | ssize_t ret; | 56 | ssize_t ret; |
57 | int err; | 57 | int err; |
58 | 58 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0a60ec5a16db..a127cc03c9fa 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1147,37 +1147,102 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1147 | return ext4_journal_get_write_access(handle, bh); | 1147 | return ext4_journal_get_write_access(handle, bh); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | /* | ||
1151 | * The idea of this helper function is following: | ||
1152 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1153 | * transaction must include the content of the newly allocated blocks. | ||
1154 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1155 | * 2006/10/14 SAW | ||
1156 | */ | ||
1157 | static int ext4_prepare_failure(struct file *file, struct page *page, | ||
1158 | unsigned from, unsigned to) | ||
1159 | { | ||
1160 | struct address_space *mapping; | ||
1161 | struct buffer_head *bh, *head, *next; | ||
1162 | unsigned block_start, block_end; | ||
1163 | unsigned blocksize; | ||
1164 | int ret; | ||
1165 | handle_t *handle = ext4_journal_current_handle(); | ||
1166 | |||
1167 | mapping = page->mapping; | ||
1168 | if (ext4_should_writeback_data(mapping->host)) { | ||
1169 | /* optimization: no constraints about data */ | ||
1170 | skip: | ||
1171 | return ext4_journal_stop(handle); | ||
1172 | } | ||
1173 | |||
1174 | head = page_buffers(page); | ||
1175 | blocksize = head->b_size; | ||
1176 | for ( bh = head, block_start = 0; | ||
1177 | bh != head || !block_start; | ||
1178 | block_start = block_end, bh = next) | ||
1179 | { | ||
1180 | next = bh->b_this_page; | ||
1181 | block_end = block_start + blocksize; | ||
1182 | if (block_end <= from) | ||
1183 | continue; | ||
1184 | if (block_start >= to) { | ||
1185 | block_start = to; | ||
1186 | break; | ||
1187 | } | ||
1188 | if (!buffer_mapped(bh)) | ||
1189 | /* prepare_write failed on this bh */ | ||
1190 | break; | ||
1191 | if (ext4_should_journal_data(mapping->host)) { | ||
1192 | ret = do_journal_get_write_access(handle, bh); | ||
1193 | if (ret) { | ||
1194 | ext4_journal_stop(handle); | ||
1195 | return ret; | ||
1196 | } | ||
1197 | } | ||
1198 | /* | ||
1199 | * block_start here becomes the first block where the current iteration | ||
1200 | * of prepare_write failed. | ||
1201 | */ | ||
1202 | } | ||
1203 | if (block_start <= from) | ||
1204 | goto skip; | ||
1205 | |||
1206 | /* commit allocated and zeroed buffers */ | ||
1207 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1208 | } | ||
1209 | |||
1150 | static int ext4_prepare_write(struct file *file, struct page *page, | 1210 | static int ext4_prepare_write(struct file *file, struct page *page, |
1151 | unsigned from, unsigned to) | 1211 | unsigned from, unsigned to) |
1152 | { | 1212 | { |
1153 | struct inode *inode = page->mapping->host; | 1213 | struct inode *inode = page->mapping->host; |
1154 | int ret, needed_blocks = ext4_writepage_trans_blocks(inode); | 1214 | int ret, ret2; |
1215 | int needed_blocks = ext4_writepage_trans_blocks(inode); | ||
1155 | handle_t *handle; | 1216 | handle_t *handle; |
1156 | int retries = 0; | 1217 | int retries = 0; |
1157 | 1218 | ||
1158 | retry: | 1219 | retry: |
1159 | handle = ext4_journal_start(inode, needed_blocks); | 1220 | handle = ext4_journal_start(inode, needed_blocks); |
1160 | if (IS_ERR(handle)) { | 1221 | if (IS_ERR(handle)) |
1161 | ret = PTR_ERR(handle); | 1222 | return PTR_ERR(handle); |
1162 | goto out; | ||
1163 | } | ||
1164 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 1223 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
1165 | ret = nobh_prepare_write(page, from, to, ext4_get_block); | 1224 | ret = nobh_prepare_write(page, from, to, ext4_get_block); |
1166 | else | 1225 | else |
1167 | ret = block_prepare_write(page, from, to, ext4_get_block); | 1226 | ret = block_prepare_write(page, from, to, ext4_get_block); |
1168 | if (ret) | 1227 | if (ret) |
1169 | goto prepare_write_failed; | 1228 | goto failure; |
1170 | 1229 | ||
1171 | if (ext4_should_journal_data(inode)) { | 1230 | if (ext4_should_journal_data(inode)) { |
1172 | ret = walk_page_buffers(handle, page_buffers(page), | 1231 | ret = walk_page_buffers(handle, page_buffers(page), |
1173 | from, to, NULL, do_journal_get_write_access); | 1232 | from, to, NULL, do_journal_get_write_access); |
1233 | if (ret) | ||
1234 | /* fatal error, just put the handle and return */ | ||
1235 | ext4_journal_stop(handle); | ||
1174 | } | 1236 | } |
1175 | prepare_write_failed: | 1237 | return ret; |
1176 | if (ret) | 1238 | |
1177 | ext4_journal_stop(handle); | 1239 | failure: |
1240 | ret2 = ext4_prepare_failure(file, page, from, to); | ||
1241 | if (ret2 < 0) | ||
1242 | return ret2; | ||
1178 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 1243 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
1179 | goto retry; | 1244 | goto retry; |
1180 | out: | 1245 | /* retry number exceeded, or other error like -EDQUOT */ |
1181 | return ret; | 1246 | return ret; |
1182 | } | 1247 | } |
1183 | 1248 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 22a737c306c7..500567dd53b6 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -256,7 +256,7 @@ flags_err: | |||
256 | #ifdef CONFIG_COMPAT | 256 | #ifdef CONFIG_COMPAT |
257 | long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 257 | long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
258 | { | 258 | { |
259 | struct inode *inode = file->f_dentry->d_inode; | 259 | struct inode *inode = file->f_path.dentry->d_inode; |
260 | int ret; | 260 | int ret; |
261 | 261 | ||
262 | /* These are just misnamed, they actually get/put from/to user an int */ | 262 | /* These are just misnamed, they actually get/put from/to user an int */ |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 8b1bd03d20f5..e5a74a5ac261 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
552 | dir->i_sb->s_blocksize - | 552 | dir->i_sb->s_blocksize - |
553 | EXT4_DIR_REC_LEN(0)); | 553 | EXT4_DIR_REC_LEN(0)); |
554 | for (; de < top; de = ext4_next_entry(de)) { | 554 | for (; de < top; de = ext4_next_entry(de)) { |
555 | if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, | ||
556 | (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) | ||
557 | +((char *)de - bh->b_data))) { | ||
558 | /* On error, skip the f_pos to the next block. */ | ||
559 | dir_file->f_pos = (dir_file->f_pos | | ||
560 | (dir->i_sb->s_blocksize - 1)) + 1; | ||
561 | brelse (bh); | ||
562 | return count; | ||
563 | } | ||
555 | ext4fs_dirhash(de->name, de->name_len, hinfo); | 564 | ext4fs_dirhash(de->name, de->name_len, hinfo); |
556 | if ((hinfo->hash < start_hash) || | 565 | if ((hinfo->hash < start_hash) || |
557 | ((hinfo->hash == start_hash) && | 566 | ((hinfo->hash == start_hash) && |
@@ -593,7 +602,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
593 | 602 | ||
594 | dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, | 603 | dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, |
595 | start_minor_hash)); | 604 | start_minor_hash)); |
596 | dir = dir_file->f_dentry->d_inode; | 605 | dir = dir_file->f_path.dentry->d_inode; |
597 | if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) { | 606 | if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) { |
598 | hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; | 607 | hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; |
599 | hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; | 608 | hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; |
@@ -604,7 +613,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
604 | } | 613 | } |
605 | hinfo.hash = start_hash; | 614 | hinfo.hash = start_hash; |
606 | hinfo.minor_hash = 0; | 615 | hinfo.minor_hash = 0; |
607 | frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); | 616 | frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err); |
608 | if (!frame) | 617 | if (!frame) |
609 | return err; | 618 | return err; |
610 | 619 | ||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b4b022aa2bc2..486a641ca71b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -486,7 +486,7 @@ static void ext4_put_super (struct super_block * sb) | |||
486 | return; | 486 | return; |
487 | } | 487 | } |
488 | 488 | ||
489 | static kmem_cache_t *ext4_inode_cachep; | 489 | static struct kmem_cache *ext4_inode_cachep; |
490 | 490 | ||
491 | /* | 491 | /* |
492 | * Called inside transaction, so use GFP_NOFS | 492 | * Called inside transaction, so use GFP_NOFS |
@@ -495,7 +495,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
495 | { | 495 | { |
496 | struct ext4_inode_info *ei; | 496 | struct ext4_inode_info *ei; |
497 | 497 | ||
498 | ei = kmem_cache_alloc(ext4_inode_cachep, SLAB_NOFS); | 498 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); |
499 | if (!ei) | 499 | if (!ei) |
500 | return NULL; | 500 | return NULL; |
501 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 501 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL |
@@ -513,7 +513,7 @@ static void ext4_destroy_inode(struct inode *inode) | |||
513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); | 513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); |
514 | } | 514 | } |
515 | 515 | ||
516 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 516 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
517 | { | 517 | { |
518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; | 518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; |
519 | 519 | ||
@@ -1321,6 +1321,12 @@ static void ext4_orphan_cleanup (struct super_block * sb, | |||
1321 | return; | 1321 | return; |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | if (bdev_read_only(sb->s_bdev)) { | ||
1325 | printk(KERN_ERR "EXT4-fs: write access " | ||
1326 | "unavailable, skipping orphan cleanup.\n"); | ||
1327 | return; | ||
1328 | } | ||
1329 | |||
1324 | if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { | 1330 | if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { |
1325 | if (es->s_last_orphan) | 1331 | if (es->s_last_orphan) |
1326 | jbd_debug(1, "Errors on filesystem, " | 1332 | jbd_debug(1, "Errors on filesystem, " |
@@ -2460,6 +2466,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2460 | struct ext4_super_block *es = sbi->s_es; | 2466 | struct ext4_super_block *es = sbi->s_es; |
2461 | ext4_fsblk_t overhead; | 2467 | ext4_fsblk_t overhead; |
2462 | int i; | 2468 | int i; |
2469 | u64 fsid; | ||
2463 | 2470 | ||
2464 | if (test_opt (sb, MINIX_DF)) | 2471 | if (test_opt (sb, MINIX_DF)) |
2465 | overhead = 0; | 2472 | overhead = 0; |
@@ -2506,6 +2513,10 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2506 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2513 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2507 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2514 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2508 | buf->f_namelen = EXT4_NAME_LEN; | 2515 | buf->f_namelen = EXT4_NAME_LEN; |
2516 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
2517 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
2518 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
2519 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
2509 | return 0; | 2520 | return 0; |
2510 | } | 2521 | } |
2511 | 2522 | ||
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 63233cd946a7..dc969c357aa1 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -459,14 +459,11 @@ static void ext4_xattr_update_super_block(handle_t *handle, | |||
459 | if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR)) | 459 | if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR)) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | lock_super(sb); | ||
463 | if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { | 462 | if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { |
464 | EXT4_SB(sb)->s_es->s_feature_compat |= | 463 | EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR); |
465 | cpu_to_le32(EXT4_FEATURE_COMPAT_EXT_ATTR); | ||
466 | sb->s_dirt = 1; | 464 | sb->s_dirt = 1; |
467 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); | 465 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); |
468 | } | 466 | } |
469 | unlock_super(sb); | ||
470 | } | 467 | } |
471 | 468 | ||
472 | /* | 469 | /* |
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 82cc4f59e3ba..05c2941c74f2 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
@@ -34,9 +34,9 @@ static inline int fat_max_cache(struct inode *inode) | |||
34 | return FAT_MAX_CACHE; | 34 | return FAT_MAX_CACHE; |
35 | } | 35 | } |
36 | 36 | ||
37 | static kmem_cache_t *fat_cache_cachep; | 37 | static struct kmem_cache *fat_cache_cachep; |
38 | 38 | ||
39 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 39 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
40 | { | 40 | { |
41 | struct fat_cache *cache = (struct fat_cache *)foo; | 41 | struct fat_cache *cache = (struct fat_cache *)foo; |
42 | 42 | ||
@@ -63,7 +63,7 @@ void fat_cache_destroy(void) | |||
63 | 63 | ||
64 | static inline struct fat_cache *fat_cache_alloc(struct inode *inode) | 64 | static inline struct fat_cache *fat_cache_alloc(struct inode *inode) |
65 | { | 65 | { |
66 | return kmem_cache_alloc(fat_cache_cachep, SLAB_KERNEL); | 66 | return kmem_cache_alloc(fat_cache_cachep, GFP_KERNEL); |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline void fat_cache_free(struct fat_cache *cache) | 69 | static inline void fat_cache_free(struct fat_cache *cache) |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 69c439f44387..c16af246d245 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -579,7 +579,7 @@ parse_record: | |||
579 | if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) | 579 | if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) |
580 | inum = inode->i_ino; | 580 | inum = inode->i_ino; |
581 | else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) { | 581 | else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) { |
582 | inum = parent_ino(filp->f_dentry); | 582 | inum = parent_ino(filp->f_path.dentry); |
583 | } else { | 583 | } else { |
584 | loff_t i_pos = fat_make_i_pos(sb, bh, de); | 584 | loff_t i_pos = fat_make_i_pos(sb, bh, de); |
585 | struct inode *tmp = fat_iget(sb, i_pos); | 585 | struct inode *tmp = fat_iget(sb, i_pos); |
@@ -643,7 +643,7 @@ out: | |||
643 | 643 | ||
644 | static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) | 644 | static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) |
645 | { | 645 | { |
646 | struct inode *inode = filp->f_dentry->d_inode; | 646 | struct inode *inode = filp->f_path.dentry->d_inode; |
647 | return __fat_readdir(inode, filp, dirent, filldir, 0, 0); | 647 | return __fat_readdir(inode, filp, dirent, filldir, 0, 0); |
648 | } | 648 | } |
649 | 649 | ||
@@ -782,7 +782,7 @@ static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, | |||
782 | 782 | ||
783 | set_fs(KERNEL_DS); | 783 | set_fs(KERNEL_DS); |
784 | lock_kernel(); | 784 | lock_kernel(); |
785 | ret = fat_dir_ioctl(file->f_dentry->d_inode, file, | 785 | ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file, |
786 | cmd, (unsigned long) &d); | 786 | cmd, (unsigned long) &d); |
787 | unlock_kernel(); | 787 | unlock_kernel(); |
788 | set_fs(oldfs); | 788 | set_fs(oldfs); |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 0aa813d944a6..c1237b70c1fe 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -92,7 +92,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /* This MUST be done before doing anything irreversible... */ | 94 | /* This MUST be done before doing anything irreversible... */ |
95 | err = notify_change(filp->f_dentry, &ia); | 95 | err = notify_change(filp->f_path.dentry, &ia); |
96 | if (err) | 96 | if (err) |
97 | goto up; | 97 | goto up; |
98 | 98 | ||
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 78945b53b0f8..a9e4688582a2 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -477,12 +477,12 @@ static void fat_put_super(struct super_block *sb) | |||
477 | kfree(sbi); | 477 | kfree(sbi); |
478 | } | 478 | } |
479 | 479 | ||
480 | static kmem_cache_t *fat_inode_cachep; | 480 | static struct kmem_cache *fat_inode_cachep; |
481 | 481 | ||
482 | static struct inode *fat_alloc_inode(struct super_block *sb) | 482 | static struct inode *fat_alloc_inode(struct super_block *sb) |
483 | { | 483 | { |
484 | struct msdos_inode_info *ei; | 484 | struct msdos_inode_info *ei; |
485 | ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL); | 485 | ei = kmem_cache_alloc(fat_inode_cachep, GFP_KERNEL); |
486 | if (!ei) | 486 | if (!ei) |
487 | return NULL; | 487 | return NULL; |
488 | return &ei->vfs_inode; | 488 | return &ei->vfs_inode; |
@@ -493,7 +493,7 @@ static void fat_destroy_inode(struct inode *inode) | |||
493 | kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); | 493 | kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); |
494 | } | 494 | } |
495 | 495 | ||
496 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 496 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
497 | { | 497 | { |
498 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; | 498 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; |
499 | 499 | ||
diff --git a/fs/fcntl.c b/fs/fcntl.c index e4f26165f12a..8e382a5d51bd 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -77,10 +77,9 @@ repeat: | |||
77 | start = files->next_fd; | 77 | start = files->next_fd; |
78 | 78 | ||
79 | newfd = start; | 79 | newfd = start; |
80 | if (start < fdt->max_fdset) { | 80 | if (start < fdt->max_fds) |
81 | newfd = find_next_zero_bit(fdt->open_fds->fds_bits, | 81 | newfd = find_next_zero_bit(fdt->open_fds->fds_bits, |
82 | fdt->max_fdset, start); | 82 | fdt->max_fds, start); |
83 | } | ||
84 | 83 | ||
85 | error = -EMFILE; | 84 | error = -EMFILE; |
86 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) | 85 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
@@ -204,7 +203,7 @@ asmlinkage long sys_dup(unsigned int fildes) | |||
204 | 203 | ||
205 | static int setfl(int fd, struct file * filp, unsigned long arg) | 204 | static int setfl(int fd, struct file * filp, unsigned long arg) |
206 | { | 205 | { |
207 | struct inode * inode = filp->f_dentry->d_inode; | 206 | struct inode * inode = filp->f_path.dentry->d_inode; |
208 | int error = 0; | 207 | int error = 0; |
209 | 208 | ||
210 | /* | 209 | /* |
@@ -553,7 +552,7 @@ int send_sigurg(struct fown_struct *fown) | |||
553 | } | 552 | } |
554 | 553 | ||
555 | static DEFINE_RWLOCK(fasync_lock); | 554 | static DEFINE_RWLOCK(fasync_lock); |
556 | static kmem_cache_t *fasync_cache __read_mostly; | 555 | static struct kmem_cache *fasync_cache __read_mostly; |
557 | 556 | ||
558 | /* | 557 | /* |
559 | * fasync_helper() is used by some character device drivers (mainly mice) | 558 | * fasync_helper() is used by some character device drivers (mainly mice) |
@@ -567,7 +566,7 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap | |||
567 | int result = 0; | 566 | int result = 0; |
568 | 567 | ||
569 | if (on) { | 568 | if (on) { |
570 | new = kmem_cache_alloc(fasync_cache, SLAB_KERNEL); | 569 | new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); |
571 | if (!new) | 570 | if (!new) |
572 | return -ENOMEM; | 571 | return -ENOMEM; |
573 | } | 572 | } |
@@ -21,7 +21,6 @@ | |||
21 | struct fdtable_defer { | 21 | struct fdtable_defer { |
22 | spinlock_t lock; | 22 | spinlock_t lock; |
23 | struct work_struct wq; | 23 | struct work_struct wq; |
24 | struct timer_list timer; | ||
25 | struct fdtable *next; | 24 | struct fdtable *next; |
26 | }; | 25 | }; |
27 | 26 | ||
@@ -33,66 +32,34 @@ struct fdtable_defer { | |||
33 | */ | 32 | */ |
34 | static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); | 33 | static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); |
35 | 34 | ||
36 | 35 | static inline void * alloc_fdmem(unsigned int size) | |
37 | /* | ||
38 | * Allocate an fd array, using kmalloc or vmalloc. | ||
39 | * Note: the array isn't cleared at allocation time. | ||
40 | */ | ||
41 | struct file ** alloc_fd_array(int num) | ||
42 | { | 36 | { |
43 | struct file **new_fds; | ||
44 | int size = num * sizeof(struct file *); | ||
45 | |||
46 | if (size <= PAGE_SIZE) | 37 | if (size <= PAGE_SIZE) |
47 | new_fds = (struct file **) kmalloc(size, GFP_KERNEL); | 38 | return kmalloc(size, GFP_KERNEL); |
48 | else | ||
49 | new_fds = (struct file **) vmalloc(size); | ||
50 | return new_fds; | ||
51 | } | ||
52 | |||
53 | void free_fd_array(struct file **array, int num) | ||
54 | { | ||
55 | int size = num * sizeof(struct file *); | ||
56 | |||
57 | if (!array) { | ||
58 | printk (KERN_ERR "free_fd_array: array = 0 (num = %d)\n", num); | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | if (num <= NR_OPEN_DEFAULT) /* Don't free the embedded fd array! */ | ||
63 | return; | ||
64 | else if (size <= PAGE_SIZE) | ||
65 | kfree(array); | ||
66 | else | 39 | else |
67 | vfree(array); | 40 | return vmalloc(size); |
68 | } | 41 | } |
69 | 42 | ||
70 | static void __free_fdtable(struct fdtable *fdt) | 43 | static inline void free_fdarr(struct fdtable *fdt) |
71 | { | 44 | { |
72 | free_fdset(fdt->open_fds, fdt->max_fdset); | 45 | if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *))) |
73 | free_fdset(fdt->close_on_exec, fdt->max_fdset); | 46 | kfree(fdt->fd); |
74 | free_fd_array(fdt->fd, fdt->max_fds); | 47 | else |
75 | kfree(fdt); | 48 | vfree(fdt->fd); |
76 | } | 49 | } |
77 | 50 | ||
78 | static void fdtable_timer(unsigned long data) | 51 | static inline void free_fdset(struct fdtable *fdt) |
79 | { | 52 | { |
80 | struct fdtable_defer *fddef = (struct fdtable_defer *)data; | 53 | if (fdt->max_fds <= (PAGE_SIZE * BITS_PER_BYTE / 2)) |
81 | 54 | kfree(fdt->open_fds); | |
82 | spin_lock(&fddef->lock); | 55 | else |
83 | /* | 56 | vfree(fdt->open_fds); |
84 | * If someone already emptied the queue return. | ||
85 | */ | ||
86 | if (!fddef->next) | ||
87 | goto out; | ||
88 | if (!schedule_work(&fddef->wq)) | ||
89 | mod_timer(&fddef->timer, 5); | ||
90 | out: | ||
91 | spin_unlock(&fddef->lock); | ||
92 | } | 57 | } |
93 | 58 | ||
94 | static void free_fdtable_work(struct fdtable_defer *f) | 59 | static void free_fdtable_work(struct work_struct *work) |
95 | { | 60 | { |
61 | struct fdtable_defer *f = | ||
62 | container_of(work, struct fdtable_defer, wq); | ||
96 | struct fdtable *fdt; | 63 | struct fdtable *fdt; |
97 | 64 | ||
98 | spin_lock_bh(&f->lock); | 65 | spin_lock_bh(&f->lock); |
@@ -101,189 +68,113 @@ static void free_fdtable_work(struct fdtable_defer *f) | |||
101 | spin_unlock_bh(&f->lock); | 68 | spin_unlock_bh(&f->lock); |
102 | while(fdt) { | 69 | while(fdt) { |
103 | struct fdtable *next = fdt->next; | 70 | struct fdtable *next = fdt->next; |
104 | __free_fdtable(fdt); | 71 | vfree(fdt->fd); |
72 | free_fdset(fdt); | ||
73 | kfree(fdt); | ||
105 | fdt = next; | 74 | fdt = next; |
106 | } | 75 | } |
107 | } | 76 | } |
108 | 77 | ||
109 | static void free_fdtable_rcu(struct rcu_head *rcu) | 78 | void free_fdtable_rcu(struct rcu_head *rcu) |
110 | { | 79 | { |
111 | struct fdtable *fdt = container_of(rcu, struct fdtable, rcu); | 80 | struct fdtable *fdt = container_of(rcu, struct fdtable, rcu); |
112 | int fdset_size, fdarray_size; | ||
113 | struct fdtable_defer *fddef; | 81 | struct fdtable_defer *fddef; |
114 | 82 | ||
115 | BUG_ON(!fdt); | 83 | BUG_ON(!fdt); |
116 | fdset_size = fdt->max_fdset / 8; | ||
117 | fdarray_size = fdt->max_fds * sizeof(struct file *); | ||
118 | 84 | ||
119 | if (fdt->free_files) { | 85 | if (fdt->max_fds <= NR_OPEN_DEFAULT) { |
120 | /* | ||
121 | * The this fdtable was embedded in the files structure | ||
122 | * and the files structure itself was getting destroyed. | ||
123 | * It is now safe to free the files structure. | ||
124 | */ | ||
125 | kmem_cache_free(files_cachep, fdt->free_files); | ||
126 | return; | ||
127 | } | ||
128 | if (fdt->max_fdset <= EMBEDDED_FD_SET_SIZE && | ||
129 | fdt->max_fds <= NR_OPEN_DEFAULT) { | ||
130 | /* | 86 | /* |
131 | * The fdtable was embedded | 87 | * This fdtable is embedded in the files structure and that |
88 | * structure itself is getting destroyed. | ||
132 | */ | 89 | */ |
90 | kmem_cache_free(files_cachep, | ||
91 | container_of(fdt, struct files_struct, fdtab)); | ||
133 | return; | 92 | return; |
134 | } | 93 | } |
135 | if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) { | 94 | if (fdt->max_fds <= (PAGE_SIZE / sizeof(struct file *))) { |
136 | kfree(fdt->open_fds); | ||
137 | kfree(fdt->close_on_exec); | ||
138 | kfree(fdt->fd); | 95 | kfree(fdt->fd); |
96 | kfree(fdt->open_fds); | ||
139 | kfree(fdt); | 97 | kfree(fdt); |
140 | } else { | 98 | } else { |
141 | fddef = &get_cpu_var(fdtable_defer_list); | 99 | fddef = &get_cpu_var(fdtable_defer_list); |
142 | spin_lock(&fddef->lock); | 100 | spin_lock(&fddef->lock); |
143 | fdt->next = fddef->next; | 101 | fdt->next = fddef->next; |
144 | fddef->next = fdt; | 102 | fddef->next = fdt; |
145 | /* | 103 | /* vmallocs are handled from the workqueue context */ |
146 | * vmallocs are handled from the workqueue context. | 104 | schedule_work(&fddef->wq); |
147 | * If the per-cpu workqueue is running, then we | ||
148 | * defer work scheduling through a timer. | ||
149 | */ | ||
150 | if (!schedule_work(&fddef->wq)) | ||
151 | mod_timer(&fddef->timer, 5); | ||
152 | spin_unlock(&fddef->lock); | 105 | spin_unlock(&fddef->lock); |
153 | put_cpu_var(fdtable_defer_list); | 106 | put_cpu_var(fdtable_defer_list); |
154 | } | 107 | } |
155 | } | 108 | } |
156 | 109 | ||
157 | void free_fdtable(struct fdtable *fdt) | ||
158 | { | ||
159 | if (fdt->free_files || | ||
160 | fdt->max_fdset > EMBEDDED_FD_SET_SIZE || | ||
161 | fdt->max_fds > NR_OPEN_DEFAULT) | ||
162 | call_rcu(&fdt->rcu, free_fdtable_rcu); | ||
163 | } | ||
164 | |||
165 | /* | 110 | /* |
166 | * Expand the fdset in the files_struct. Called with the files spinlock | 111 | * Expand the fdset in the files_struct. Called with the files spinlock |
167 | * held for write. | 112 | * held for write. |
168 | */ | 113 | */ |
169 | static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt) | 114 | static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) |
170 | { | 115 | { |
171 | int i; | 116 | unsigned int cpy, set; |
172 | int count; | ||
173 | |||
174 | BUG_ON(nfdt->max_fdset < fdt->max_fdset); | ||
175 | BUG_ON(nfdt->max_fds < fdt->max_fds); | ||
176 | /* Copy the existing tables and install the new pointers */ | ||
177 | |||
178 | i = fdt->max_fdset / (sizeof(unsigned long) * 8); | ||
179 | count = (nfdt->max_fdset - fdt->max_fdset) / 8; | ||
180 | |||
181 | /* | ||
182 | * Don't copy the entire array if the current fdset is | ||
183 | * not yet initialised. | ||
184 | */ | ||
185 | if (i) { | ||
186 | memcpy (nfdt->open_fds, fdt->open_fds, | ||
187 | fdt->max_fdset/8); | ||
188 | memcpy (nfdt->close_on_exec, fdt->close_on_exec, | ||
189 | fdt->max_fdset/8); | ||
190 | memset (&nfdt->open_fds->fds_bits[i], 0, count); | ||
191 | memset (&nfdt->close_on_exec->fds_bits[i], 0, count); | ||
192 | } | ||
193 | 117 | ||
194 | /* Don't copy/clear the array if we are creating a new | 118 | BUG_ON(nfdt->max_fds < ofdt->max_fds); |
195 | fd array for fork() */ | 119 | if (ofdt->max_fds == 0) |
196 | if (fdt->max_fds) { | 120 | return; |
197 | memcpy(nfdt->fd, fdt->fd, | ||
198 | fdt->max_fds * sizeof(struct file *)); | ||
199 | /* clear the remainder of the array */ | ||
200 | memset(&nfdt->fd[fdt->max_fds], 0, | ||
201 | (nfdt->max_fds - fdt->max_fds) * | ||
202 | sizeof(struct file *)); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Allocate an fdset array, using kmalloc or vmalloc. | ||
208 | * Note: the array isn't cleared at allocation time. | ||
209 | */ | ||
210 | fd_set * alloc_fdset(int num) | ||
211 | { | ||
212 | fd_set *new_fdset; | ||
213 | int size = num / 8; | ||
214 | 121 | ||
215 | if (size <= PAGE_SIZE) | 122 | cpy = ofdt->max_fds * sizeof(struct file *); |
216 | new_fdset = (fd_set *) kmalloc(size, GFP_KERNEL); | 123 | set = (nfdt->max_fds - ofdt->max_fds) * sizeof(struct file *); |
217 | else | 124 | memcpy(nfdt->fd, ofdt->fd, cpy); |
218 | new_fdset = (fd_set *) vmalloc(size); | 125 | memset((char *)(nfdt->fd) + cpy, 0, set); |
219 | return new_fdset; | 126 | |
127 | cpy = ofdt->max_fds / BITS_PER_BYTE; | ||
128 | set = (nfdt->max_fds - ofdt->max_fds) / BITS_PER_BYTE; | ||
129 | memcpy(nfdt->open_fds, ofdt->open_fds, cpy); | ||
130 | memset((char *)(nfdt->open_fds) + cpy, 0, set); | ||
131 | memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy); | ||
132 | memset((char *)(nfdt->close_on_exec) + cpy, 0, set); | ||
220 | } | 133 | } |
221 | 134 | ||
222 | void free_fdset(fd_set *array, int num) | 135 | static struct fdtable * alloc_fdtable(unsigned int nr) |
223 | { | 136 | { |
224 | if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */ | 137 | struct fdtable *fdt; |
225 | return; | 138 | char *data; |
226 | else if (num <= 8 * PAGE_SIZE) | ||
227 | kfree(array); | ||
228 | else | ||
229 | vfree(array); | ||
230 | } | ||
231 | 139 | ||
232 | static struct fdtable *alloc_fdtable(int nr) | 140 | /* |
233 | { | 141 | * Figure out how many fds we actually want to support in this fdtable. |
234 | struct fdtable *fdt = NULL; | 142 | * Allocation steps are keyed to the size of the fdarray, since it |
235 | int nfds = 0; | 143 | * grows far faster than any of the other dynamic data. We try to fit |
236 | fd_set *new_openset = NULL, *new_execset = NULL; | 144 | * the fdarray into comfortable page-tuned chunks: starting at 1024B |
237 | struct file **new_fds; | 145 | * and growing in powers of two from there on. |
146 | */ | ||
147 | nr /= (1024 / sizeof(struct file *)); | ||
148 | nr = roundup_pow_of_two(nr + 1); | ||
149 | nr *= (1024 / sizeof(struct file *)); | ||
150 | if (nr > NR_OPEN) | ||
151 | nr = NR_OPEN; | ||
238 | 152 | ||
239 | fdt = kzalloc(sizeof(*fdt), GFP_KERNEL); | 153 | fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); |
240 | if (!fdt) | 154 | if (!fdt) |
241 | goto out; | 155 | goto out; |
242 | 156 | fdt->max_fds = nr; | |
243 | nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1)); | 157 | data = alloc_fdmem(nr * sizeof(struct file *)); |
244 | if (nfds > NR_OPEN) | 158 | if (!data) |
245 | nfds = NR_OPEN; | 159 | goto out_fdt; |
246 | 160 | fdt->fd = (struct file **)data; | |
247 | new_openset = alloc_fdset(nfds); | 161 | data = alloc_fdmem(max_t(unsigned int, |
248 | new_execset = alloc_fdset(nfds); | 162 | 2 * nr / BITS_PER_BYTE, L1_CACHE_BYTES)); |
249 | if (!new_openset || !new_execset) | 163 | if (!data) |
250 | goto out; | 164 | goto out_arr; |
251 | fdt->open_fds = new_openset; | 165 | fdt->open_fds = (fd_set *)data; |
252 | fdt->close_on_exec = new_execset; | 166 | data += nr / BITS_PER_BYTE; |
253 | fdt->max_fdset = nfds; | 167 | fdt->close_on_exec = (fd_set *)data; |
168 | INIT_RCU_HEAD(&fdt->rcu); | ||
169 | fdt->next = NULL; | ||
254 | 170 | ||
255 | nfds = NR_OPEN_DEFAULT; | ||
256 | /* | ||
257 | * Expand to the max in easy steps, and keep expanding it until | ||
258 | * we have enough for the requested fd array size. | ||
259 | */ | ||
260 | do { | ||
261 | #if NR_OPEN_DEFAULT < 256 | ||
262 | if (nfds < 256) | ||
263 | nfds = 256; | ||
264 | else | ||
265 | #endif | ||
266 | if (nfds < (PAGE_SIZE / sizeof(struct file *))) | ||
267 | nfds = PAGE_SIZE / sizeof(struct file *); | ||
268 | else { | ||
269 | nfds = nfds * 2; | ||
270 | if (nfds > NR_OPEN) | ||
271 | nfds = NR_OPEN; | ||
272 | } | ||
273 | } while (nfds <= nr); | ||
274 | new_fds = alloc_fd_array(nfds); | ||
275 | if (!new_fds) | ||
276 | goto out2; | ||
277 | fdt->fd = new_fds; | ||
278 | fdt->max_fds = nfds; | ||
279 | fdt->free_files = NULL; | ||
280 | return fdt; | 171 | return fdt; |
281 | out2: | 172 | |
282 | nfds = fdt->max_fdset; | 173 | out_arr: |
283 | out: | 174 | free_fdarr(fdt); |
284 | free_fdset(new_openset, nfds); | 175 | out_fdt: |
285 | free_fdset(new_execset, nfds); | ||
286 | kfree(fdt); | 176 | kfree(fdt); |
177 | out: | ||
287 | return NULL; | 178 | return NULL; |
288 | } | 179 | } |
289 | 180 | ||
@@ -310,14 +201,17 @@ static int expand_fdtable(struct files_struct *files, int nr) | |||
310 | * we dropped the lock | 201 | * we dropped the lock |
311 | */ | 202 | */ |
312 | cur_fdt = files_fdtable(files); | 203 | cur_fdt = files_fdtable(files); |
313 | if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) { | 204 | if (nr >= cur_fdt->max_fds) { |
314 | /* Continue as planned */ | 205 | /* Continue as planned */ |
315 | copy_fdtable(new_fdt, cur_fdt); | 206 | copy_fdtable(new_fdt, cur_fdt); |
316 | rcu_assign_pointer(files->fdt, new_fdt); | 207 | rcu_assign_pointer(files->fdt, new_fdt); |
317 | free_fdtable(cur_fdt); | 208 | if (cur_fdt->max_fds > NR_OPEN_DEFAULT) |
209 | free_fdtable(cur_fdt); | ||
318 | } else { | 210 | } else { |
319 | /* Somebody else expanded, so undo our attempt */ | 211 | /* Somebody else expanded, so undo our attempt */ |
320 | __free_fdtable(new_fdt); | 212 | free_fdarr(new_fdt); |
213 | free_fdset(new_fdt); | ||
214 | kfree(new_fdt); | ||
321 | } | 215 | } |
322 | return 1; | 216 | return 1; |
323 | } | 217 | } |
@@ -336,11 +230,10 @@ int expand_files(struct files_struct *files, int nr) | |||
336 | 230 | ||
337 | fdt = files_fdtable(files); | 231 | fdt = files_fdtable(files); |
338 | /* Do we need to expand? */ | 232 | /* Do we need to expand? */ |
339 | if (nr < fdt->max_fdset && nr < fdt->max_fds) | 233 | if (nr < fdt->max_fds) |
340 | return 0; | 234 | return 0; |
341 | /* Can we expand? */ | 235 | /* Can we expand? */ |
342 | if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN || | 236 | if (nr >= NR_OPEN) |
343 | nr >= NR_OPEN) | ||
344 | return -EMFILE; | 237 | return -EMFILE; |
345 | 238 | ||
346 | /* All good, so we try */ | 239 | /* All good, so we try */ |
@@ -351,10 +244,7 @@ static void __devinit fdtable_defer_list_init(int cpu) | |||
351 | { | 244 | { |
352 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); | 245 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); |
353 | spin_lock_init(&fddef->lock); | 246 | spin_lock_init(&fddef->lock); |
354 | INIT_WORK(&fddef->wq, (void (*)(void *))free_fdtable_work, fddef); | 247 | INIT_WORK(&fddef->wq, free_fdtable_work); |
355 | init_timer(&fddef->timer); | ||
356 | fddef->timer.data = (unsigned long)fddef; | ||
357 | fddef->timer.function = fdtable_timer; | ||
358 | fddef->next = NULL; | 248 | fddef->next = NULL; |
359 | } | 249 | } |
360 | 250 | ||
diff --git a/fs/file_table.c b/fs/file_table.c index 24f25a057d9c..4c17a18d8c10 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -152,8 +152,8 @@ EXPORT_SYMBOL(fput); | |||
152 | */ | 152 | */ |
153 | void fastcall __fput(struct file *file) | 153 | void fastcall __fput(struct file *file) |
154 | { | 154 | { |
155 | struct dentry *dentry = file->f_dentry; | 155 | struct dentry *dentry = file->f_path.dentry; |
156 | struct vfsmount *mnt = file->f_vfsmnt; | 156 | struct vfsmount *mnt = file->f_path.mnt; |
157 | struct inode *inode = dentry->d_inode; | 157 | struct inode *inode = dentry->d_inode; |
158 | 158 | ||
159 | might_sleep(); | 159 | might_sleep(); |
@@ -176,8 +176,8 @@ void fastcall __fput(struct file *file) | |||
176 | put_write_access(inode); | 176 | put_write_access(inode); |
177 | put_pid(file->f_owner.pid); | 177 | put_pid(file->f_owner.pid); |
178 | file_kill(file); | 178 | file_kill(file); |
179 | file->f_dentry = NULL; | 179 | file->f_path.dentry = NULL; |
180 | file->f_vfsmnt = NULL; | 180 | file->f_path.mnt = NULL; |
181 | file_free(file); | 181 | file_free(file); |
182 | dput(dentry); | 182 | dput(dentry); |
183 | mntput(mnt); | 183 | mntput(mnt); |
@@ -271,7 +271,7 @@ int fs_may_remount_ro(struct super_block *sb) | |||
271 | file_list_lock(); | 271 | file_list_lock(); |
272 | list_for_each(p, &sb->s_files) { | 272 | list_for_each(p, &sb->s_files) { |
273 | struct file *file = list_entry(p, struct file, f_u.fu_list); | 273 | struct file *file = list_entry(p, struct file, f_u.fu_list); |
274 | struct inode *inode = file->f_dentry->d_inode; | 274 | struct inode *inode = file->f_path.dentry->d_inode; |
275 | 275 | ||
276 | /* File with pending delete? */ | 276 | /* File with pending delete? */ |
277 | if (inode->i_nlink == 0) | 277 | if (inode->i_nlink == 0) |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 4786d51ad3bd..0b7ae897cb78 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -46,7 +46,7 @@ extern const struct address_space_operations vxfs_immed_aops; | |||
46 | 46 | ||
47 | extern struct inode_operations vxfs_immed_symlink_iops; | 47 | extern struct inode_operations vxfs_immed_symlink_iops; |
48 | 48 | ||
49 | kmem_cache_t *vxfs_inode_cachep; | 49 | struct kmem_cache *vxfs_inode_cachep; |
50 | 50 | ||
51 | 51 | ||
52 | #ifdef DIAGNOSTIC | 52 | #ifdef DIAGNOSTIC |
@@ -103,7 +103,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) | |||
103 | struct vxfs_inode_info *vip; | 103 | struct vxfs_inode_info *vip; |
104 | struct vxfs_dinode *dip; | 104 | struct vxfs_dinode *dip; |
105 | 105 | ||
106 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) | 106 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) |
107 | goto fail; | 107 | goto fail; |
108 | dip = (struct vxfs_dinode *)(bp->b_data + offset); | 108 | dip = (struct vxfs_dinode *)(bp->b_data + offset); |
109 | memcpy(vip, dip, sizeof(*vip)); | 109 | memcpy(vip, dip, sizeof(*vip)); |
@@ -145,7 +145,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) | |||
145 | struct vxfs_dinode *dip; | 145 | struct vxfs_dinode *dip; |
146 | caddr_t kaddr = (char *)page_address(pp); | 146 | caddr_t kaddr = (char *)page_address(pp); |
147 | 147 | ||
148 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) | 148 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) |
149 | goto fail; | 149 | goto fail; |
150 | dip = (struct vxfs_dinode *)(kaddr + offset); | 150 | dip = (struct vxfs_dinode *)(kaddr + offset); |
151 | memcpy(vip, dip, sizeof(*vip)); | 151 | memcpy(vip, dip, sizeof(*vip)); |
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 43886fa00a2a..3995d7fbedab 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c | |||
@@ -240,7 +240,7 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) | |||
240 | static int | 240 | static int |
241 | vxfs_readdir(struct file *fp, void *retp, filldir_t filler) | 241 | vxfs_readdir(struct file *fp, void *retp, filldir_t filler) |
242 | { | 242 | { |
243 | struct inode *ip = fp->f_dentry->d_inode; | 243 | struct inode *ip = fp->f_path.dentry->d_inode; |
244 | struct super_block *sbp = ip->i_sb; | 244 | struct super_block *sbp = ip->i_sb; |
245 | u_long bsize = sbp->s_blocksize; | 245 | u_long bsize = sbp->s_blocksize; |
246 | u_long page, npages, block, pblocks, nblocks, offset; | 246 | u_long page, npages, block, pblocks, nblocks, offset; |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 16b39c053d47..8c58bd453993 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -23,7 +23,7 @@ static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file) | |||
23 | { | 23 | { |
24 | struct fuse_conn *fc; | 24 | struct fuse_conn *fc; |
25 | mutex_lock(&fuse_mutex); | 25 | mutex_lock(&fuse_mutex); |
26 | fc = file->f_dentry->d_inode->i_private; | 26 | fc = file->f_path.dentry->d_inode->i_private; |
27 | if (fc) | 27 | if (fc) |
28 | fc = fuse_conn_get(fc); | 28 | fc = fuse_conn_get(fc); |
29 | mutex_unlock(&fuse_mutex); | 29 | mutex_unlock(&fuse_mutex); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 66571eafbb1e..357764d85ff1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | MODULE_ALIAS_MISCDEV(FUSE_MINOR); | 20 | MODULE_ALIAS_MISCDEV(FUSE_MINOR); |
21 | 21 | ||
22 | static kmem_cache_t *fuse_req_cachep; | 22 | static struct kmem_cache *fuse_req_cachep; |
23 | 23 | ||
24 | static struct fuse_conn *fuse_get_conn(struct file *file) | 24 | static struct fuse_conn *fuse_get_conn(struct file *file) |
25 | { | 25 | { |
@@ -41,7 +41,7 @@ static void fuse_request_init(struct fuse_req *req) | |||
41 | 41 | ||
42 | struct fuse_req *fuse_request_alloc(void) | 42 | struct fuse_req *fuse_request_alloc(void) |
43 | { | 43 | { |
44 | struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL); | 44 | struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); |
45 | if (req) | 45 | if (req) |
46 | fuse_request_init(req); | 46 | fuse_request_init(req); |
47 | return req; | 47 | return req; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index c71a6c092ad9..40080477ceb4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -141,9 +141,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
141 | struct fuse_req *forget_req; | 141 | struct fuse_req *forget_req; |
142 | struct dentry *parent; | 142 | struct dentry *parent; |
143 | 143 | ||
144 | /* Doesn't hurt to "reset" the validity timeout */ | ||
145 | fuse_invalidate_entry_cache(entry); | ||
146 | |||
147 | /* For negative dentries, always do a fresh lookup */ | 144 | /* For negative dentries, always do a fresh lookup */ |
148 | if (!inode) | 145 | if (!inode) |
149 | return 0; | 146 | return 0; |
@@ -859,7 +856,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
859 | int err; | 856 | int err; |
860 | size_t nbytes; | 857 | size_t nbytes; |
861 | struct page *page; | 858 | struct page *page; |
862 | struct inode *inode = file->f_dentry->d_inode; | 859 | struct inode *inode = file->f_path.dentry->d_inode; |
863 | struct fuse_conn *fc = get_fuse_conn(inode); | 860 | struct fuse_conn *fc = get_fuse_conn(inode); |
864 | struct fuse_req *req; | 861 | struct fuse_req *req; |
865 | 862 | ||
@@ -1027,6 +1024,8 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1027 | if (attr->ia_valid & ATTR_SIZE) { | 1024 | if (attr->ia_valid & ATTR_SIZE) { |
1028 | unsigned long limit; | 1025 | unsigned long limit; |
1029 | is_truncate = 1; | 1026 | is_truncate = 1; |
1027 | if (IS_SWAPFILE(inode)) | ||
1028 | return -ETXTBSY; | ||
1030 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 1029 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
1031 | if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { | 1030 | if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { |
1032 | send_sig(SIGXFSZ, current, 0); | 1031 | send_sig(SIGXFSZ, current, 0); |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 763a50daf1c0..f63efe1337ec 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -141,8 +141,8 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) | |||
141 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); | 141 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); |
142 | 142 | ||
143 | /* Hold vfsmount and dentry until release is finished */ | 143 | /* Hold vfsmount and dentry until release is finished */ |
144 | req->vfsmount = mntget(file->f_vfsmnt); | 144 | req->vfsmount = mntget(file->f_path.mnt); |
145 | req->dentry = dget(file->f_dentry); | 145 | req->dentry = dget(file->f_path.dentry); |
146 | request_send_background(fc, req); | 146 | request_send_background(fc, req); |
147 | } | 147 | } |
148 | 148 | ||
@@ -184,7 +184,7 @@ static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) | |||
184 | 184 | ||
185 | static int fuse_flush(struct file *file, fl_owner_t id) | 185 | static int fuse_flush(struct file *file, fl_owner_t id) |
186 | { | 186 | { |
187 | struct inode *inode = file->f_dentry->d_inode; | 187 | struct inode *inode = file->f_path.dentry->d_inode; |
188 | struct fuse_conn *fc = get_fuse_conn(inode); | 188 | struct fuse_conn *fc = get_fuse_conn(inode); |
189 | struct fuse_file *ff = file->private_data; | 189 | struct fuse_file *ff = file->private_data; |
190 | struct fuse_req *req; | 190 | struct fuse_req *req; |
@@ -483,10 +483,8 @@ static int fuse_commit_write(struct file *file, struct page *page, | |||
483 | i_size_write(inode, pos); | 483 | i_size_write(inode, pos); |
484 | spin_unlock(&fc->lock); | 484 | spin_unlock(&fc->lock); |
485 | 485 | ||
486 | if (offset == 0 && to == PAGE_CACHE_SIZE) { | 486 | if (offset == 0 && to == PAGE_CACHE_SIZE) |
487 | clear_page_dirty(page); | ||
488 | SetPageUptodate(page); | 487 | SetPageUptodate(page); |
489 | } | ||
490 | } | 488 | } |
491 | fuse_invalidate_attr(inode); | 489 | fuse_invalidate_attr(inode); |
492 | return err; | 490 | return err; |
@@ -533,7 +531,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, | |||
533 | static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | 531 | static ssize_t fuse_direct_io(struct file *file, const char __user *buf, |
534 | size_t count, loff_t *ppos, int write) | 532 | size_t count, loff_t *ppos, int write) |
535 | { | 533 | { |
536 | struct inode *inode = file->f_dentry->d_inode; | 534 | struct inode *inode = file->f_path.dentry->d_inode; |
537 | struct fuse_conn *fc = get_fuse_conn(inode); | 535 | struct fuse_conn *fc = get_fuse_conn(inode); |
538 | size_t nmax = write ? fc->max_write : fc->max_read; | 536 | size_t nmax = write ? fc->max_write : fc->max_read; |
539 | loff_t pos = *ppos; | 537 | loff_t pos = *ppos; |
@@ -607,7 +605,7 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, | |||
607 | static ssize_t fuse_direct_write(struct file *file, const char __user *buf, | 605 | static ssize_t fuse_direct_write(struct file *file, const char __user *buf, |
608 | size_t count, loff_t *ppos) | 606 | size_t count, loff_t *ppos) |
609 | { | 607 | { |
610 | struct inode *inode = file->f_dentry->d_inode; | 608 | struct inode *inode = file->f_path.dentry->d_inode; |
611 | ssize_t res; | 609 | ssize_t res; |
612 | /* Don't allow parallel writes to the same file */ | 610 | /* Don't allow parallel writes to the same file */ |
613 | mutex_lock(&inode->i_mutex); | 611 | mutex_lock(&inode->i_mutex); |
@@ -662,7 +660,7 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, | |||
662 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, | 660 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, |
663 | const struct file_lock *fl, int opcode, pid_t pid) | 661 | const struct file_lock *fl, int opcode, pid_t pid) |
664 | { | 662 | { |
665 | struct inode *inode = file->f_dentry->d_inode; | 663 | struct inode *inode = file->f_path.dentry->d_inode; |
666 | struct fuse_conn *fc = get_fuse_conn(inode); | 664 | struct fuse_conn *fc = get_fuse_conn(inode); |
667 | struct fuse_file *ff = file->private_data; | 665 | struct fuse_file *ff = file->private_data; |
668 | struct fuse_lk_in *arg = &req->misc.lk_in; | 666 | struct fuse_lk_in *arg = &req->misc.lk_in; |
@@ -682,7 +680,7 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file, | |||
682 | 680 | ||
683 | static int fuse_getlk(struct file *file, struct file_lock *fl) | 681 | static int fuse_getlk(struct file *file, struct file_lock *fl) |
684 | { | 682 | { |
685 | struct inode *inode = file->f_dentry->d_inode; | 683 | struct inode *inode = file->f_path.dentry->d_inode; |
686 | struct fuse_conn *fc = get_fuse_conn(inode); | 684 | struct fuse_conn *fc = get_fuse_conn(inode); |
687 | struct fuse_req *req; | 685 | struct fuse_req *req; |
688 | struct fuse_lk_out outarg; | 686 | struct fuse_lk_out outarg; |
@@ -707,7 +705,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) | |||
707 | 705 | ||
708 | static int fuse_setlk(struct file *file, struct file_lock *fl) | 706 | static int fuse_setlk(struct file *file, struct file_lock *fl) |
709 | { | 707 | { |
710 | struct inode *inode = file->f_dentry->d_inode; | 708 | struct inode *inode = file->f_path.dentry->d_inode; |
711 | struct fuse_conn *fc = get_fuse_conn(inode); | 709 | struct fuse_conn *fc = get_fuse_conn(inode); |
712 | struct fuse_req *req; | 710 | struct fuse_req *req; |
713 | int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; | 711 | int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; |
@@ -734,7 +732,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl) | |||
734 | 732 | ||
735 | static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) | 733 | static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) |
736 | { | 734 | { |
737 | struct inode *inode = file->f_dentry->d_inode; | 735 | struct inode *inode = file->f_path.dentry->d_inode; |
738 | struct fuse_conn *fc = get_fuse_conn(inode); | 736 | struct fuse_conn *fc = get_fuse_conn(inode); |
739 | int err; | 737 | int err; |
740 | 738 | ||
@@ -754,6 +752,42 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) | |||
754 | return err; | 752 | return err; |
755 | } | 753 | } |
756 | 754 | ||
755 | static sector_t fuse_bmap(struct address_space *mapping, sector_t block) | ||
756 | { | ||
757 | struct inode *inode = mapping->host; | ||
758 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
759 | struct fuse_req *req; | ||
760 | struct fuse_bmap_in inarg; | ||
761 | struct fuse_bmap_out outarg; | ||
762 | int err; | ||
763 | |||
764 | if (!inode->i_sb->s_bdev || fc->no_bmap) | ||
765 | return 0; | ||
766 | |||
767 | req = fuse_get_req(fc); | ||
768 | if (IS_ERR(req)) | ||
769 | return 0; | ||
770 | |||
771 | memset(&inarg, 0, sizeof(inarg)); | ||
772 | inarg.block = block; | ||
773 | inarg.blocksize = inode->i_sb->s_blocksize; | ||
774 | req->in.h.opcode = FUSE_BMAP; | ||
775 | req->in.h.nodeid = get_node_id(inode); | ||
776 | req->in.numargs = 1; | ||
777 | req->in.args[0].size = sizeof(inarg); | ||
778 | req->in.args[0].value = &inarg; | ||
779 | req->out.numargs = 1; | ||
780 | req->out.args[0].size = sizeof(outarg); | ||
781 | req->out.args[0].value = &outarg; | ||
782 | request_send(fc, req); | ||
783 | err = req->out.h.error; | ||
784 | fuse_put_request(fc, req); | ||
785 | if (err == -ENOSYS) | ||
786 | fc->no_bmap = 1; | ||
787 | |||
788 | return err ? 0 : outarg.block; | ||
789 | } | ||
790 | |||
757 | static const struct file_operations fuse_file_operations = { | 791 | static const struct file_operations fuse_file_operations = { |
758 | .llseek = generic_file_llseek, | 792 | .llseek = generic_file_llseek, |
759 | .read = do_sync_read, | 793 | .read = do_sync_read, |
@@ -787,6 +821,7 @@ static const struct address_space_operations fuse_file_aops = { | |||
787 | .commit_write = fuse_commit_write, | 821 | .commit_write = fuse_commit_write, |
788 | .readpages = fuse_readpages, | 822 | .readpages = fuse_readpages, |
789 | .set_page_dirty = fuse_set_page_dirty, | 823 | .set_page_dirty = fuse_set_page_dirty, |
824 | .bmap = fuse_bmap, | ||
790 | }; | 825 | }; |
791 | 826 | ||
792 | void fuse_init_file_inode(struct inode *inode) | 827 | void fuse_init_file_inode(struct inode *inode) |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 91edb8932d90..b98b20de7405 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -298,6 +298,9 @@ struct fuse_conn { | |||
298 | reply, before any other request, and never cleared */ | 298 | reply, before any other request, and never cleared */ |
299 | unsigned conn_error : 1; | 299 | unsigned conn_error : 1; |
300 | 300 | ||
301 | /** Connection successful. Only set in INIT */ | ||
302 | unsigned conn_init : 1; | ||
303 | |||
301 | /** Do readpages asynchronously? Only set in INIT */ | 304 | /** Do readpages asynchronously? Only set in INIT */ |
302 | unsigned async_read : 1; | 305 | unsigned async_read : 1; |
303 | 306 | ||
@@ -339,6 +342,9 @@ struct fuse_conn { | |||
339 | /** Is interrupt not implemented by fs? */ | 342 | /** Is interrupt not implemented by fs? */ |
340 | unsigned no_interrupt : 1; | 343 | unsigned no_interrupt : 1; |
341 | 344 | ||
345 | /** Is bmap not implemented by fs? */ | ||
346 | unsigned no_bmap : 1; | ||
347 | |||
342 | /** The number of requests waiting for completion */ | 348 | /** The number of requests waiting for completion */ |
343 | atomic_t num_waiting; | 349 | atomic_t num_waiting; |
344 | 350 | ||
@@ -365,6 +371,9 @@ struct fuse_conn { | |||
365 | 371 | ||
366 | /** Key for lock owner ID scrambling */ | 372 | /** Key for lock owner ID scrambling */ |
367 | u32 scramble_key[4]; | 373 | u32 scramble_key[4]; |
374 | |||
375 | /** Reserved request for the DESTROY message */ | ||
376 | struct fuse_req *destroy_req; | ||
368 | }; | 377 | }; |
369 | 378 | ||
370 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) | 379 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fc4203570370..12450d2b320e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -22,7 +22,7 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |||
22 | MODULE_DESCRIPTION("Filesystem in Userspace"); | 22 | MODULE_DESCRIPTION("Filesystem in Userspace"); |
23 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
24 | 24 | ||
25 | static kmem_cache_t *fuse_inode_cachep; | 25 | static struct kmem_cache *fuse_inode_cachep; |
26 | struct list_head fuse_conn_list; | 26 | struct list_head fuse_conn_list; |
27 | DEFINE_MUTEX(fuse_mutex); | 27 | DEFINE_MUTEX(fuse_mutex); |
28 | 28 | ||
@@ -39,6 +39,7 @@ struct fuse_mount_data { | |||
39 | unsigned group_id_present : 1; | 39 | unsigned group_id_present : 1; |
40 | unsigned flags; | 40 | unsigned flags; |
41 | unsigned max_read; | 41 | unsigned max_read; |
42 | unsigned blksize; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct inode *fuse_alloc_inode(struct super_block *sb) | 45 | static struct inode *fuse_alloc_inode(struct super_block *sb) |
@@ -46,7 +47,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
46 | struct inode *inode; | 47 | struct inode *inode; |
47 | struct fuse_inode *fi; | 48 | struct fuse_inode *fi; |
48 | 49 | ||
49 | inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL); | 50 | inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL); |
50 | if (!inode) | 51 | if (!inode) |
51 | return NULL; | 52 | return NULL; |
52 | 53 | ||
@@ -205,10 +206,23 @@ static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
205 | fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); | 206 | fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); |
206 | } | 207 | } |
207 | 208 | ||
209 | static void fuse_send_destroy(struct fuse_conn *fc) | ||
210 | { | ||
211 | struct fuse_req *req = fc->destroy_req; | ||
212 | if (req && fc->conn_init) { | ||
213 | fc->destroy_req = NULL; | ||
214 | req->in.h.opcode = FUSE_DESTROY; | ||
215 | req->force = 1; | ||
216 | request_send(fc, req); | ||
217 | fuse_put_request(fc, req); | ||
218 | } | ||
219 | } | ||
220 | |||
208 | static void fuse_put_super(struct super_block *sb) | 221 | static void fuse_put_super(struct super_block *sb) |
209 | { | 222 | { |
210 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 223 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
211 | 224 | ||
225 | fuse_send_destroy(fc); | ||
212 | spin_lock(&fc->lock); | 226 | spin_lock(&fc->lock); |
213 | fc->connected = 0; | 227 | fc->connected = 0; |
214 | fc->blocked = 0; | 228 | fc->blocked = 0; |
@@ -274,6 +288,7 @@ enum { | |||
274 | OPT_DEFAULT_PERMISSIONS, | 288 | OPT_DEFAULT_PERMISSIONS, |
275 | OPT_ALLOW_OTHER, | 289 | OPT_ALLOW_OTHER, |
276 | OPT_MAX_READ, | 290 | OPT_MAX_READ, |
291 | OPT_BLKSIZE, | ||
277 | OPT_ERR | 292 | OPT_ERR |
278 | }; | 293 | }; |
279 | 294 | ||
@@ -285,14 +300,16 @@ static match_table_t tokens = { | |||
285 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, | 300 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, |
286 | {OPT_ALLOW_OTHER, "allow_other"}, | 301 | {OPT_ALLOW_OTHER, "allow_other"}, |
287 | {OPT_MAX_READ, "max_read=%u"}, | 302 | {OPT_MAX_READ, "max_read=%u"}, |
303 | {OPT_BLKSIZE, "blksize=%u"}, | ||
288 | {OPT_ERR, NULL} | 304 | {OPT_ERR, NULL} |
289 | }; | 305 | }; |
290 | 306 | ||
291 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | 307 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) |
292 | { | 308 | { |
293 | char *p; | 309 | char *p; |
294 | memset(d, 0, sizeof(struct fuse_mount_data)); | 310 | memset(d, 0, sizeof(struct fuse_mount_data)); |
295 | d->max_read = ~0; | 311 | d->max_read = ~0; |
312 | d->blksize = 512; | ||
296 | 313 | ||
297 | while ((p = strsep(&opt, ",")) != NULL) { | 314 | while ((p = strsep(&opt, ",")) != NULL) { |
298 | int token; | 315 | int token; |
@@ -345,6 +362,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | |||
345 | d->max_read = value; | 362 | d->max_read = value; |
346 | break; | 363 | break; |
347 | 364 | ||
365 | case OPT_BLKSIZE: | ||
366 | if (!is_bdev || match_int(&args[0], &value)) | ||
367 | return 0; | ||
368 | d->blksize = value; | ||
369 | break; | ||
370 | |||
348 | default: | 371 | default: |
349 | return 0; | 372 | return 0; |
350 | } | 373 | } |
@@ -400,6 +423,8 @@ static struct fuse_conn *new_conn(void) | |||
400 | void fuse_conn_put(struct fuse_conn *fc) | 423 | void fuse_conn_put(struct fuse_conn *fc) |
401 | { | 424 | { |
402 | if (atomic_dec_and_test(&fc->count)) { | 425 | if (atomic_dec_and_test(&fc->count)) { |
426 | if (fc->destroy_req) | ||
427 | fuse_request_free(fc->destroy_req); | ||
403 | mutex_destroy(&fc->inst_mutex); | 428 | mutex_destroy(&fc->inst_mutex); |
404 | kfree(fc); | 429 | kfree(fc); |
405 | } | 430 | } |
@@ -456,6 +481,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
456 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | 481 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); |
457 | fc->minor = arg->minor; | 482 | fc->minor = arg->minor; |
458 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 483 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
484 | fc->conn_init = 1; | ||
459 | } | 485 | } |
460 | fuse_put_request(fc, req); | 486 | fuse_put_request(fc, req); |
461 | fc->blocked = 0; | 487 | fc->blocked = 0; |
@@ -500,15 +526,23 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | struct dentry *root_dentry; | 526 | struct dentry *root_dentry; |
501 | struct fuse_req *init_req; | 527 | struct fuse_req *init_req; |
502 | int err; | 528 | int err; |
529 | int is_bdev = sb->s_bdev != NULL; | ||
503 | 530 | ||
504 | if (sb->s_flags & MS_MANDLOCK) | 531 | if (sb->s_flags & MS_MANDLOCK) |
505 | return -EINVAL; | 532 | return -EINVAL; |
506 | 533 | ||
507 | if (!parse_fuse_opt((char *) data, &d)) | 534 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
508 | return -EINVAL; | 535 | return -EINVAL; |
509 | 536 | ||
510 | sb->s_blocksize = PAGE_CACHE_SIZE; | 537 | if (is_bdev) { |
511 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 538 | #ifdef CONFIG_BLOCK |
539 | if (!sb_set_blocksize(sb, d.blksize)) | ||
540 | return -EINVAL; | ||
541 | #endif | ||
542 | } else { | ||
543 | sb->s_blocksize = PAGE_CACHE_SIZE; | ||
544 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | ||
545 | } | ||
512 | sb->s_magic = FUSE_SUPER_MAGIC; | 546 | sb->s_magic = FUSE_SUPER_MAGIC; |
513 | sb->s_op = &fuse_super_operations; | 547 | sb->s_op = &fuse_super_operations; |
514 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 548 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
@@ -547,6 +581,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
547 | if (!init_req) | 581 | if (!init_req) |
548 | goto err_put_root; | 582 | goto err_put_root; |
549 | 583 | ||
584 | if (is_bdev) { | ||
585 | fc->destroy_req = fuse_request_alloc(); | ||
586 | if (!fc->destroy_req) | ||
587 | goto err_put_root; | ||
588 | } | ||
589 | |||
550 | mutex_lock(&fuse_mutex); | 590 | mutex_lock(&fuse_mutex); |
551 | err = -EINVAL; | 591 | err = -EINVAL; |
552 | if (file->private_data) | 592 | if (file->private_data) |
@@ -598,10 +638,47 @@ static struct file_system_type fuse_fs_type = { | |||
598 | .kill_sb = kill_anon_super, | 638 | .kill_sb = kill_anon_super, |
599 | }; | 639 | }; |
600 | 640 | ||
641 | #ifdef CONFIG_BLOCK | ||
642 | static int fuse_get_sb_blk(struct file_system_type *fs_type, | ||
643 | int flags, const char *dev_name, | ||
644 | void *raw_data, struct vfsmount *mnt) | ||
645 | { | ||
646 | return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super, | ||
647 | mnt); | ||
648 | } | ||
649 | |||
650 | static struct file_system_type fuseblk_fs_type = { | ||
651 | .owner = THIS_MODULE, | ||
652 | .name = "fuseblk", | ||
653 | .get_sb = fuse_get_sb_blk, | ||
654 | .kill_sb = kill_block_super, | ||
655 | .fs_flags = FS_REQUIRES_DEV, | ||
656 | }; | ||
657 | |||
658 | static inline int register_fuseblk(void) | ||
659 | { | ||
660 | return register_filesystem(&fuseblk_fs_type); | ||
661 | } | ||
662 | |||
663 | static inline void unregister_fuseblk(void) | ||
664 | { | ||
665 | unregister_filesystem(&fuseblk_fs_type); | ||
666 | } | ||
667 | #else | ||
668 | static inline int register_fuseblk(void) | ||
669 | { | ||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static inline void unregister_fuseblk(void) | ||
674 | { | ||
675 | } | ||
676 | #endif | ||
677 | |||
601 | static decl_subsys(fuse, NULL, NULL); | 678 | static decl_subsys(fuse, NULL, NULL); |
602 | static decl_subsys(connections, NULL, NULL); | 679 | static decl_subsys(connections, NULL, NULL); |
603 | 680 | ||
604 | static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, | 681 | static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, |
605 | unsigned long flags) | 682 | unsigned long flags) |
606 | { | 683 | { |
607 | struct inode * inode = foo; | 684 | struct inode * inode = foo; |
@@ -617,24 +694,34 @@ static int __init fuse_fs_init(void) | |||
617 | 694 | ||
618 | err = register_filesystem(&fuse_fs_type); | 695 | err = register_filesystem(&fuse_fs_type); |
619 | if (err) | 696 | if (err) |
620 | printk("fuse: failed to register filesystem\n"); | 697 | goto out; |
621 | else { | ||
622 | fuse_inode_cachep = kmem_cache_create("fuse_inode", | ||
623 | sizeof(struct fuse_inode), | ||
624 | 0, SLAB_HWCACHE_ALIGN, | ||
625 | fuse_inode_init_once, NULL); | ||
626 | if (!fuse_inode_cachep) { | ||
627 | unregister_filesystem(&fuse_fs_type); | ||
628 | err = -ENOMEM; | ||
629 | } | ||
630 | } | ||
631 | 698 | ||
699 | err = register_fuseblk(); | ||
700 | if (err) | ||
701 | goto out_unreg; | ||
702 | |||
703 | fuse_inode_cachep = kmem_cache_create("fuse_inode", | ||
704 | sizeof(struct fuse_inode), | ||
705 | 0, SLAB_HWCACHE_ALIGN, | ||
706 | fuse_inode_init_once, NULL); | ||
707 | err = -ENOMEM; | ||
708 | if (!fuse_inode_cachep) | ||
709 | goto out_unreg2; | ||
710 | |||
711 | return 0; | ||
712 | |||
713 | out_unreg2: | ||
714 | unregister_fuseblk(); | ||
715 | out_unreg: | ||
716 | unregister_filesystem(&fuse_fs_type); | ||
717 | out: | ||
632 | return err; | 718 | return err; |
633 | } | 719 | } |
634 | 720 | ||
635 | static void fuse_fs_cleanup(void) | 721 | static void fuse_fs_cleanup(void) |
636 | { | 722 | { |
637 | unregister_filesystem(&fuse_fs_type); | 723 | unregister_filesystem(&fuse_fs_type); |
724 | unregister_fuseblk(); | ||
638 | kmem_cache_destroy(fuse_inode_cachep); | 725 | kmem_cache_destroy(fuse_inode_cachep); |
639 | } | 726 | } |
640 | 727 | ||
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 8c27de8b9568..6a2ffa2db14f 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig | |||
@@ -2,6 +2,7 @@ config GFS2_FS | |||
2 | tristate "GFS2 file system support" | 2 | tristate "GFS2 file system support" |
3 | depends on EXPERIMENTAL | 3 | depends on EXPERIMENTAL |
4 | select FS_POSIX_ACL | 4 | select FS_POSIX_ACL |
5 | select CRC32 | ||
5 | help | 6 | help |
6 | A cluster filesystem. | 7 | A cluster filesystem. |
7 | 8 | ||
@@ -33,7 +34,9 @@ config GFS2_FS_LOCKING_NOLOCK | |||
33 | 34 | ||
34 | config GFS2_FS_LOCKING_DLM | 35 | config GFS2_FS_LOCKING_DLM |
35 | tristate "GFS2 DLM locking module" | 36 | tristate "GFS2 DLM locking module" |
36 | depends on GFS2_FS | 37 | depends on GFS2_FS && NET && INET && (IPV6 || IPV6=n) |
38 | select IP_SCTP if DLM_SCTP | ||
39 | select CONFIGFS_FS | ||
37 | select DLM | 40 | select DLM |
38 | help | 41 | help |
39 | Multiple node locking module for GFS2 | 42 | Multiple node locking module for GFS2 |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 5f959b8ce406..6e80844367ee 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -74,11 +74,11 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
74 | { | 74 | { |
75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) | 75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) |
76 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
77 | if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) | 77 | if (current->fsuid != ip->i_inode.i_uid && !capable(CAP_FOWNER)) |
78 | return -EPERM; | 78 | return -EPERM; |
79 | if (S_ISLNK(ip->i_di.di_mode)) | 79 | if (S_ISLNK(ip->i_inode.i_mode)) |
80 | return -EOPNOTSUPP; | 80 | return -EOPNOTSUPP; |
81 | if (!access && !S_ISDIR(ip->i_di.di_mode)) | 81 | if (!access && !S_ISDIR(ip->i_inode.i_mode)) |
82 | return -EACCES; | 82 | return -EACCES; |
83 | 83 | ||
84 | return 0; | 84 | return 0; |
@@ -145,14 +145,14 @@ out: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * gfs2_check_acl_locked - Check an ACL to see if we're allowed to do something | 148 | * gfs2_check_acl - Check an ACL to see if we're allowed to do something |
149 | * @inode: the file we want to do something to | 149 | * @inode: the file we want to do something to |
150 | * @mask: what we want to do | 150 | * @mask: what we want to do |
151 | * | 151 | * |
152 | * Returns: errno | 152 | * Returns: errno |
153 | */ | 153 | */ |
154 | 154 | ||
155 | int gfs2_check_acl_locked(struct inode *inode, int mask) | 155 | int gfs2_check_acl(struct inode *inode, int mask) |
156 | { | 156 | { |
157 | struct posix_acl *acl = NULL; | 157 | struct posix_acl *acl = NULL; |
158 | int error; | 158 | int error; |
@@ -170,21 +170,6 @@ int gfs2_check_acl_locked(struct inode *inode, int mask) | |||
170 | return -EAGAIN; | 170 | return -EAGAIN; |
171 | } | 171 | } |
172 | 172 | ||
173 | int gfs2_check_acl(struct inode *inode, int mask) | ||
174 | { | ||
175 | struct gfs2_inode *ip = GFS2_I(inode); | ||
176 | struct gfs2_holder i_gh; | ||
177 | int error; | ||
178 | |||
179 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
180 | if (!error) { | ||
181 | error = gfs2_check_acl_locked(inode, mask); | ||
182 | gfs2_glock_dq_uninit(&i_gh); | ||
183 | } | ||
184 | |||
185 | return error; | ||
186 | } | ||
187 | |||
188 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) | 173 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) |
189 | { | 174 | { |
190 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 175 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
@@ -198,10 +183,10 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode) | |||
198 | error = gfs2_meta_inode_buffer(ip, &dibh); | 183 | error = gfs2_meta_inode_buffer(ip, &dibh); |
199 | if (!error) { | 184 | if (!error) { |
200 | gfs2_assert_withdraw(sdp, | 185 | gfs2_assert_withdraw(sdp, |
201 | (ip->i_di.di_mode & S_IFMT) == (mode & S_IFMT)); | 186 | (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT)); |
202 | ip->i_di.di_mode = mode; | 187 | ip->i_inode.i_mode = mode; |
203 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 188 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
204 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 189 | gfs2_dinode_out(ip, dibh->b_data); |
205 | brelse(dibh); | 190 | brelse(dibh); |
206 | } | 191 | } |
207 | 192 | ||
@@ -215,12 +200,12 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
215 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 200 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
216 | struct posix_acl *acl = NULL, *clone; | 201 | struct posix_acl *acl = NULL, *clone; |
217 | struct gfs2_ea_request er; | 202 | struct gfs2_ea_request er; |
218 | mode_t mode = ip->i_di.di_mode; | 203 | mode_t mode = ip->i_inode.i_mode; |
219 | int error; | 204 | int error; |
220 | 205 | ||
221 | if (!sdp->sd_args.ar_posix_acl) | 206 | if (!sdp->sd_args.ar_posix_acl) |
222 | return 0; | 207 | return 0; |
223 | if (S_ISLNK(ip->i_di.di_mode)) | 208 | if (S_ISLNK(ip->i_inode.i_mode)) |
224 | return 0; | 209 | return 0; |
225 | 210 | ||
226 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 211 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
@@ -232,7 +217,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
232 | return error; | 217 | return error; |
233 | if (!acl) { | 218 | if (!acl) { |
234 | mode &= ~current->fs->umask; | 219 | mode &= ~current->fs->umask; |
235 | if (mode != ip->i_di.di_mode) | 220 | if (mode != ip->i_inode.i_mode) |
236 | error = munge_mode(ip, mode); | 221 | error = munge_mode(ip, mode); |
237 | return error; | 222 | return error; |
238 | } | 223 | } |
@@ -244,7 +229,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
244 | posix_acl_release(acl); | 229 | posix_acl_release(acl); |
245 | acl = clone; | 230 | acl = clone; |
246 | 231 | ||
247 | if (S_ISDIR(ip->i_di.di_mode)) { | 232 | if (S_ISDIR(ip->i_inode.i_mode)) { |
248 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | 233 | er.er_name = GFS2_POSIX_ACL_DEFAULT; |
249 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | 234 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; |
250 | error = gfs2_system_eaops.eo_set(ip, &er); | 235 | error = gfs2_system_eaops.eo_set(ip, &er); |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 05c294fe0d78..6751930bfb64 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
@@ -31,7 +31,6 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, | |||
31 | struct gfs2_ea_request *er, | 31 | struct gfs2_ea_request *er, |
32 | int *remove, mode_t *mode); | 32 | int *remove, mode_t *mode); |
33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); | 33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); |
34 | int gfs2_check_acl_locked(struct inode *inode, int mask); | ||
35 | int gfs2_check_acl(struct inode *inode, int mask); | 34 | int gfs2_check_acl(struct inode *inode, int mask); |
36 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); | 35 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); |
37 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 36 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 06e9a8cb45e9..8240c1ff94f4 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -38,8 +38,8 @@ struct metapath { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, | 40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, |
41 | struct buffer_head *bh, u64 *top, | 41 | struct buffer_head *bh, __be64 *top, |
42 | u64 *bottom, unsigned int height, | 42 | __be64 *bottom, unsigned int height, |
43 | void *data); | 43 | void *data); |
44 | 44 | ||
45 | struct strip_mine { | 45 | struct strip_mine { |
@@ -163,6 +163,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
163 | if (ip->i_di.di_size) { | 163 | if (ip->i_di.di_size) { |
164 | *(__be64 *)(di + 1) = cpu_to_be64(block); | 164 | *(__be64 *)(di + 1) = cpu_to_be64(block); |
165 | ip->i_di.di_blocks++; | 165 | ip->i_di.di_blocks++; |
166 | gfs2_set_inode_blocks(&ip->i_inode); | ||
166 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 167 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
167 | } | 168 | } |
168 | 169 | ||
@@ -230,7 +231,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
230 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; | 231 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; |
231 | struct gfs2_dinode *di; | 232 | struct gfs2_dinode *di; |
232 | int error; | 233 | int error; |
233 | u64 *bp; | 234 | __be64 *bp; |
234 | u64 bn; | 235 | u64 bn; |
235 | unsigned n; | 236 | unsigned n; |
236 | 237 | ||
@@ -255,7 +256,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
255 | GFS2_FORMAT_IN); | 256 | GFS2_FORMAT_IN); |
256 | gfs2_buffer_clear_tail(blocks[n], | 257 | gfs2_buffer_clear_tail(blocks[n], |
257 | sizeof(struct gfs2_meta_header)); | 258 | sizeof(struct gfs2_meta_header)); |
258 | bp = (u64 *)(blocks[n]->b_data + | 259 | bp = (__be64 *)(blocks[n]->b_data + |
259 | sizeof(struct gfs2_meta_header)); | 260 | sizeof(struct gfs2_meta_header)); |
260 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); | 261 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); |
261 | brelse(blocks[n]); | 262 | brelse(blocks[n]); |
@@ -272,6 +273,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
272 | *(__be64 *)(di + 1) = cpu_to_be64(bn); | 273 | *(__be64 *)(di + 1) = cpu_to_be64(bn); |
273 | ip->i_di.di_height += new_height; | 274 | ip->i_di.di_height += new_height; |
274 | ip->i_di.di_blocks += new_height; | 275 | ip->i_di.di_blocks += new_height; |
276 | gfs2_set_inode_blocks(&ip->i_inode); | ||
275 | di->di_height = cpu_to_be16(ip->i_di.di_height); | 277 | di->di_height = cpu_to_be16(ip->i_di.di_height); |
276 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 278 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
277 | brelse(dibh); | 279 | brelse(dibh); |
@@ -360,15 +362,15 @@ static void find_metapath(struct gfs2_inode *ip, u64 block, | |||
360 | * metadata tree. | 362 | * metadata tree. |
361 | */ | 363 | */ |
362 | 364 | ||
363 | static inline u64 *metapointer(struct buffer_head *bh, int *boundary, | 365 | static inline __be64 *metapointer(struct buffer_head *bh, int *boundary, |
364 | unsigned int height, const struct metapath *mp) | 366 | unsigned int height, const struct metapath *mp) |
365 | { | 367 | { |
366 | unsigned int head_size = (height > 0) ? | 368 | unsigned int head_size = (height > 0) ? |
367 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); | 369 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); |
368 | u64 *ptr; | 370 | __be64 *ptr; |
369 | *boundary = 0; | 371 | *boundary = 0; |
370 | ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height]; | 372 | ptr = ((__be64 *)(bh->b_data + head_size)) + mp->mp_list[height]; |
371 | if (ptr + 1 == (u64 *)(bh->b_data + bh->b_size)) | 373 | if (ptr + 1 == (__be64 *)(bh->b_data + bh->b_size)) |
372 | *boundary = 1; | 374 | *boundary = 1; |
373 | return ptr; | 375 | return ptr; |
374 | } | 376 | } |
@@ -394,7 +396,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
394 | int *new, u64 *block) | 396 | int *new, u64 *block) |
395 | { | 397 | { |
396 | int boundary; | 398 | int boundary; |
397 | u64 *ptr = metapointer(bh, &boundary, height, mp); | 399 | __be64 *ptr = metapointer(bh, &boundary, height, mp); |
398 | 400 | ||
399 | if (*ptr) { | 401 | if (*ptr) { |
400 | *block = be64_to_cpu(*ptr); | 402 | *block = be64_to_cpu(*ptr); |
@@ -415,17 +417,35 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
415 | 417 | ||
416 | *ptr = cpu_to_be64(*block); | 418 | *ptr = cpu_to_be64(*block); |
417 | ip->i_di.di_blocks++; | 419 | ip->i_di.di_blocks++; |
420 | gfs2_set_inode_blocks(&ip->i_inode); | ||
418 | 421 | ||
419 | *new = 1; | 422 | *new = 1; |
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
426 | static inline void bmap_lock(struct inode *inode, int create) | ||
427 | { | ||
428 | struct gfs2_inode *ip = GFS2_I(inode); | ||
429 | if (create) | ||
430 | down_write(&ip->i_rw_mutex); | ||
431 | else | ||
432 | down_read(&ip->i_rw_mutex); | ||
433 | } | ||
434 | |||
435 | static inline void bmap_unlock(struct inode *inode, int create) | ||
436 | { | ||
437 | struct gfs2_inode *ip = GFS2_I(inode); | ||
438 | if (create) | ||
439 | up_write(&ip->i_rw_mutex); | ||
440 | else | ||
441 | up_read(&ip->i_rw_mutex); | ||
442 | } | ||
443 | |||
423 | /** | 444 | /** |
424 | * gfs2_block_pointers - Map a block from an inode to a disk block | 445 | * gfs2_block_map - Map a block from an inode to a disk block |
425 | * @inode: The inode | 446 | * @inode: The inode |
426 | * @lblock: The logical block number | 447 | * @lblock: The logical block number |
427 | * @map_bh: The bh to be mapped | 448 | * @bh_map: The bh to be mapped |
428 | * @mp: metapath to use | ||
429 | * | 449 | * |
430 | * Find the block number on the current device which corresponds to an | 450 | * Find the block number on the current device which corresponds to an |
431 | * inode's block. If the block had to be created, "new" will be set. | 451 | * inode's block. If the block had to be created, "new" will be set. |
@@ -433,8 +453,8 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
433 | * Returns: errno | 453 | * Returns: errno |
434 | */ | 454 | */ |
435 | 455 | ||
436 | static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | 456 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, |
437 | struct buffer_head *bh_map, struct metapath *mp) | 457 | struct buffer_head *bh_map) |
438 | { | 458 | { |
439 | struct gfs2_inode *ip = GFS2_I(inode); | 459 | struct gfs2_inode *ip = GFS2_I(inode); |
440 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 460 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -448,57 +468,61 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
448 | u64 dblock = 0; | 468 | u64 dblock = 0; |
449 | int boundary; | 469 | int boundary; |
450 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; | 470 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; |
471 | struct metapath mp; | ||
472 | u64 size; | ||
451 | 473 | ||
452 | BUG_ON(maxlen == 0); | 474 | BUG_ON(maxlen == 0); |
453 | 475 | ||
454 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) | 476 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) |
455 | return 0; | 477 | return 0; |
456 | 478 | ||
479 | bmap_lock(inode, create); | ||
480 | clear_buffer_mapped(bh_map); | ||
481 | clear_buffer_new(bh_map); | ||
482 | clear_buffer_boundary(bh_map); | ||
457 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; | 483 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; |
458 | 484 | size = (lblock + 1) * bsize; | |
459 | height = calc_tree_height(ip, (lblock + 1) * bsize); | 485 | |
460 | if (ip->i_di.di_height < height) { | 486 | if (size > ip->i_di.di_size) { |
461 | if (!create) | 487 | height = calc_tree_height(ip, size); |
462 | return 0; | 488 | if (ip->i_di.di_height < height) { |
463 | 489 | if (!create) | |
464 | error = build_height(inode, height); | 490 | goto out_ok; |
465 | if (error) | 491 | |
466 | return error; | 492 | error = build_height(inode, height); |
493 | if (error) | ||
494 | goto out_fail; | ||
495 | } | ||
467 | } | 496 | } |
468 | 497 | ||
469 | find_metapath(ip, lblock, mp); | 498 | find_metapath(ip, lblock, &mp); |
470 | end_of_metadata = ip->i_di.di_height - 1; | 499 | end_of_metadata = ip->i_di.di_height - 1; |
471 | |||
472 | error = gfs2_meta_inode_buffer(ip, &bh); | 500 | error = gfs2_meta_inode_buffer(ip, &bh); |
473 | if (error) | 501 | if (error) |
474 | return error; | 502 | goto out_fail; |
475 | 503 | ||
476 | for (x = 0; x < end_of_metadata; x++) { | 504 | for (x = 0; x < end_of_metadata; x++) { |
477 | lookup_block(ip, bh, x, mp, create, &new, &dblock); | 505 | lookup_block(ip, bh, x, &mp, create, &new, &dblock); |
478 | brelse(bh); | 506 | brelse(bh); |
479 | if (!dblock) | 507 | if (!dblock) |
480 | return 0; | 508 | goto out_ok; |
481 | 509 | ||
482 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); | 510 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); |
483 | if (error) | 511 | if (error) |
484 | return error; | 512 | goto out_fail; |
485 | } | 513 | } |
486 | 514 | ||
487 | boundary = lookup_block(ip, bh, end_of_metadata, mp, create, &new, &dblock); | 515 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock); |
488 | clear_buffer_mapped(bh_map); | ||
489 | clear_buffer_new(bh_map); | ||
490 | clear_buffer_boundary(bh_map); | ||
491 | |||
492 | if (dblock) { | 516 | if (dblock) { |
493 | map_bh(bh_map, inode->i_sb, dblock); | 517 | map_bh(bh_map, inode->i_sb, dblock); |
494 | if (boundary) | 518 | if (boundary) |
495 | set_buffer_boundary(bh); | 519 | set_buffer_boundary(bh_map); |
496 | if (new) { | 520 | if (new) { |
497 | struct buffer_head *dibh; | 521 | struct buffer_head *dibh; |
498 | error = gfs2_meta_inode_buffer(ip, &dibh); | 522 | error = gfs2_meta_inode_buffer(ip, &dibh); |
499 | if (!error) { | 523 | if (!error) { |
500 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 524 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
501 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 525 | gfs2_dinode_out(ip, dibh->b_data); |
502 | brelse(dibh); | 526 | brelse(dibh); |
503 | } | 527 | } |
504 | set_buffer_new(bh_map); | 528 | set_buffer_new(bh_map); |
@@ -507,8 +531,8 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
507 | while(--maxlen && !buffer_boundary(bh_map)) { | 531 | while(--maxlen && !buffer_boundary(bh_map)) { |
508 | u64 eblock; | 532 | u64 eblock; |
509 | 533 | ||
510 | mp->mp_list[end_of_metadata]++; | 534 | mp.mp_list[end_of_metadata]++; |
511 | boundary = lookup_block(ip, bh, end_of_metadata, mp, 0, &new, &eblock); | 535 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, 0, &new, &eblock); |
512 | if (eblock != ++dblock) | 536 | if (eblock != ++dblock) |
513 | break; | 537 | break; |
514 | bh_map->b_size += (1 << inode->i_blkbits); | 538 | bh_map->b_size += (1 << inode->i_blkbits); |
@@ -518,43 +542,15 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
518 | } | 542 | } |
519 | out_brelse: | 543 | out_brelse: |
520 | brelse(bh); | 544 | brelse(bh); |
521 | return 0; | 545 | out_ok: |
522 | } | 546 | error = 0; |
523 | 547 | out_fail: | |
524 | |||
525 | static inline void bmap_lock(struct inode *inode, int create) | ||
526 | { | ||
527 | struct gfs2_inode *ip = GFS2_I(inode); | ||
528 | if (create) | ||
529 | down_write(&ip->i_rw_mutex); | ||
530 | else | ||
531 | down_read(&ip->i_rw_mutex); | ||
532 | } | ||
533 | |||
534 | static inline void bmap_unlock(struct inode *inode, int create) | ||
535 | { | ||
536 | struct gfs2_inode *ip = GFS2_I(inode); | ||
537 | if (create) | ||
538 | up_write(&ip->i_rw_mutex); | ||
539 | else | ||
540 | up_read(&ip->i_rw_mutex); | ||
541 | } | ||
542 | |||
543 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, | ||
544 | struct buffer_head *bh) | ||
545 | { | ||
546 | struct metapath mp; | ||
547 | int ret; | ||
548 | |||
549 | bmap_lock(inode, create); | ||
550 | ret = gfs2_block_pointers(inode, lblock, create, bh, &mp); | ||
551 | bmap_unlock(inode, create); | 548 | bmap_unlock(inode, create); |
552 | return ret; | 549 | return error; |
553 | } | 550 | } |
554 | 551 | ||
555 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) | 552 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) |
556 | { | 553 | { |
557 | struct metapath mp; | ||
558 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; | 554 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; |
559 | int ret; | 555 | int ret; |
560 | int create = *new; | 556 | int create = *new; |
@@ -564,9 +560,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
564 | BUG_ON(!new); | 560 | BUG_ON(!new); |
565 | 561 | ||
566 | bh.b_size = 1 << (inode->i_blkbits + 5); | 562 | bh.b_size = 1 << (inode->i_blkbits + 5); |
567 | bmap_lock(inode, create); | 563 | ret = gfs2_block_map(inode, lblock, create, &bh); |
568 | ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp); | ||
569 | bmap_unlock(inode, create); | ||
570 | *extlen = bh.b_size >> inode->i_blkbits; | 564 | *extlen = bh.b_size >> inode->i_blkbits; |
571 | *dblock = bh.b_blocknr; | 565 | *dblock = bh.b_blocknr; |
572 | if (buffer_new(&bh)) | 566 | if (buffer_new(&bh)) |
@@ -600,7 +594,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
600 | { | 594 | { |
601 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 595 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
602 | struct buffer_head *bh = NULL; | 596 | struct buffer_head *bh = NULL; |
603 | u64 *top, *bottom; | 597 | __be64 *top, *bottom; |
604 | u64 bn; | 598 | u64 bn; |
605 | int error; | 599 | int error; |
606 | int mh_size = sizeof(struct gfs2_meta_header); | 600 | int mh_size = sizeof(struct gfs2_meta_header); |
@@ -611,17 +605,17 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
611 | return error; | 605 | return error; |
612 | dibh = bh; | 606 | dibh = bh; |
613 | 607 | ||
614 | top = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; | 608 | top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; |
615 | bottom = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; | 609 | bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; |
616 | } else { | 610 | } else { |
617 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); | 611 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); |
618 | if (error) | 612 | if (error) |
619 | return error; | 613 | return error; |
620 | 614 | ||
621 | top = (u64 *)(bh->b_data + mh_size) + | 615 | top = (__be64 *)(bh->b_data + mh_size) + |
622 | (first ? mp->mp_list[height] : 0); | 616 | (first ? mp->mp_list[height] : 0); |
623 | 617 | ||
624 | bottom = (u64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; | 618 | bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; |
625 | } | 619 | } |
626 | 620 | ||
627 | error = bc(ip, dibh, bh, top, bottom, height, data); | 621 | error = bc(ip, dibh, bh, top, bottom, height, data); |
@@ -660,7 +654,7 @@ out: | |||
660 | */ | 654 | */ |
661 | 655 | ||
662 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | 656 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, |
663 | struct buffer_head *bh, u64 *top, u64 *bottom, | 657 | struct buffer_head *bh, __be64 *top, __be64 *bottom, |
664 | unsigned int height, void *data) | 658 | unsigned int height, void *data) |
665 | { | 659 | { |
666 | struct strip_mine *sm = data; | 660 | struct strip_mine *sm = data; |
@@ -668,7 +662,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
668 | struct gfs2_rgrp_list rlist; | 662 | struct gfs2_rgrp_list rlist; |
669 | u64 bn, bstart; | 663 | u64 bn, bstart; |
670 | u32 blen; | 664 | u32 blen; |
671 | u64 *p; | 665 | __be64 *p; |
672 | unsigned int rg_blocks = 0; | 666 | unsigned int rg_blocks = 0; |
673 | int metadata; | 667 | int metadata; |
674 | unsigned int revokes = 0; | 668 | unsigned int revokes = 0; |
@@ -770,6 +764,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
770 | if (!ip->i_di.di_blocks) | 764 | if (!ip->i_di.di_blocks) |
771 | gfs2_consist_inode(ip); | 765 | gfs2_consist_inode(ip); |
772 | ip->i_di.di_blocks--; | 766 | ip->i_di.di_blocks--; |
767 | gfs2_set_inode_blocks(&ip->i_inode); | ||
773 | } | 768 | } |
774 | if (bstart) { | 769 | if (bstart) { |
775 | if (metadata) | 770 | if (metadata) |
@@ -778,9 +773,9 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
778 | gfs2_free_data(ip, bstart, blen); | 773 | gfs2_free_data(ip, bstart, blen); |
779 | } | 774 | } |
780 | 775 | ||
781 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 776 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
782 | 777 | ||
783 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 778 | gfs2_dinode_out(ip, dibh->b_data); |
784 | 779 | ||
785 | up_write(&ip->i_rw_mutex); | 780 | up_write(&ip->i_rw_mutex); |
786 | 781 | ||
@@ -819,7 +814,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
819 | if (error) | 814 | if (error) |
820 | goto out; | 815 | goto out; |
821 | 816 | ||
822 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 817 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
823 | if (error) | 818 | if (error) |
824 | goto out_gunlock_q; | 819 | goto out_gunlock_q; |
825 | 820 | ||
@@ -853,14 +848,14 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
853 | } | 848 | } |
854 | 849 | ||
855 | ip->i_di.di_size = size; | 850 | ip->i_di.di_size = size; |
856 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 851 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
857 | 852 | ||
858 | error = gfs2_meta_inode_buffer(ip, &dibh); | 853 | error = gfs2_meta_inode_buffer(ip, &dibh); |
859 | if (error) | 854 | if (error) |
860 | goto out_end_trans; | 855 | goto out_end_trans; |
861 | 856 | ||
862 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
863 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
864 | brelse(dibh); | 859 | brelse(dibh); |
865 | 860 | ||
866 | out_end_trans: | 861 | out_end_trans: |
@@ -968,9 +963,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
968 | 963 | ||
969 | if (gfs2_is_stuffed(ip)) { | 964 | if (gfs2_is_stuffed(ip)) { |
970 | ip->i_di.di_size = size; | 965 | ip->i_di.di_size = size; |
971 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 966 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
972 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 967 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
973 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 968 | gfs2_dinode_out(ip, dibh->b_data); |
974 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); | 969 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); |
975 | error = 1; | 970 | error = 1; |
976 | 971 | ||
@@ -980,10 +975,10 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
980 | 975 | ||
981 | if (!error) { | 976 | if (!error) { |
982 | ip->i_di.di_size = size; | 977 | ip->i_di.di_size = size; |
983 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 978 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
984 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; | 979 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; |
985 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 980 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
986 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 981 | gfs2_dinode_out(ip, dibh->b_data); |
987 | } | 982 | } |
988 | } | 983 | } |
989 | 984 | ||
@@ -1053,11 +1048,11 @@ static int trunc_end(struct gfs2_inode *ip) | |||
1053 | ip->i_num.no_addr; | 1048 | ip->i_num.no_addr; |
1054 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 1049 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
1055 | } | 1050 | } |
1056 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1051 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1057 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; | 1052 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; |
1058 | 1053 | ||
1059 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1054 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1060 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1055 | gfs2_dinode_out(ip, dibh->b_data); |
1061 | brelse(dibh); | 1056 | brelse(dibh); |
1062 | 1057 | ||
1063 | out: | 1058 | out: |
@@ -1109,7 +1104,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) | |||
1109 | { | 1104 | { |
1110 | int error; | 1105 | int error; |
1111 | 1106 | ||
1112 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode))) | 1107 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) |
1113 | return -EINVAL; | 1108 | return -EINVAL; |
1114 | 1109 | ||
1115 | if (size > ip->i_di.di_size) | 1110 | if (size > ip->i_di.di_size) |
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index cab1f68d4685..683cb5bda870 100644 --- a/fs/gfs2/daemon.c +++ b/fs/gfs2/daemon.c | |||
@@ -112,6 +112,7 @@ int gfs2_logd(void *data) | |||
112 | struct gfs2_sbd *sdp = data; | 112 | struct gfs2_sbd *sdp = data; |
113 | struct gfs2_holder ji_gh; | 113 | struct gfs2_holder ji_gh; |
114 | unsigned long t; | 114 | unsigned long t; |
115 | int need_flush; | ||
115 | 116 | ||
116 | while (!kthread_should_stop()) { | 117 | while (!kthread_should_stop()) { |
117 | /* Advance the log tail */ | 118 | /* Advance the log tail */ |
@@ -120,8 +121,10 @@ int gfs2_logd(void *data) | |||
120 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; | 121 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; |
121 | 122 | ||
122 | gfs2_ail1_empty(sdp, DIO_ALL); | 123 | gfs2_ail1_empty(sdp, DIO_ALL); |
123 | 124 | gfs2_log_lock(sdp); | |
124 | if (time_after_eq(jiffies, t)) { | 125 | need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); |
126 | gfs2_log_unlock(sdp); | ||
127 | if (need_flush || time_after_eq(jiffies, t)) { | ||
125 | gfs2_log_flush(sdp, NULL); | 128 | gfs2_log_flush(sdp, NULL); |
126 | sdp->sd_log_flush_time = jiffies; | 129 | sdp->sd_log_flush_time = jiffies; |
127 | } | 130 | } |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index e24af28b1a12..0fdcb7713cd9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -131,8 +131,8 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
132 | if (ip->i_di.di_size < offset + size) | 132 | if (ip->i_di.di_size < offset + size) |
133 | ip->i_di.di_size = offset + size; | 133 | ip->i_di.di_size = offset + size; |
134 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 134 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
135 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 135 | gfs2_dinode_out(ip, dibh->b_data); |
136 | 136 | ||
137 | brelse(dibh); | 137 | brelse(dibh); |
138 | 138 | ||
@@ -229,10 +229,10 @@ out: | |||
229 | 229 | ||
230 | if (ip->i_di.di_size < offset + copied) | 230 | if (ip->i_di.di_size < offset + copied) |
231 | ip->i_di.di_size = offset + copied; | 231 | ip->i_di.di_size = offset + copied; |
232 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 232 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
233 | 233 | ||
234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
235 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 235 | gfs2_dinode_out(ip, dibh->b_data); |
236 | brelse(dibh); | 236 | brelse(dibh); |
237 | 237 | ||
238 | return copied; | 238 | return copied; |
@@ -340,10 +340,15 @@ fail: | |||
340 | return (copied) ? copied : error; | 340 | return (copied) ? copied : error; |
341 | } | 341 | } |
342 | 342 | ||
343 | static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) | ||
344 | { | ||
345 | return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0; | ||
346 | } | ||
347 | |||
343 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, | 348 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, |
344 | const struct qstr *name, int ret) | 349 | const struct qstr *name, int ret) |
345 | { | 350 | { |
346 | if (dent->de_inum.no_addr != 0 && | 351 | if (!gfs2_dirent_sentinel(dent) && |
347 | be32_to_cpu(dent->de_hash) == name->hash && | 352 | be32_to_cpu(dent->de_hash) == name->hash && |
348 | be16_to_cpu(dent->de_name_len) == name->len && | 353 | be16_to_cpu(dent->de_name_len) == name->len && |
349 | memcmp(dent+1, name->name, name->len) == 0) | 354 | memcmp(dent+1, name->name, name->len) == 0) |
@@ -388,7 +393,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, | |||
388 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 393 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
389 | unsigned totlen = be16_to_cpu(dent->de_rec_len); | 394 | unsigned totlen = be16_to_cpu(dent->de_rec_len); |
390 | 395 | ||
391 | if (!dent->de_inum.no_addr) | 396 | if (gfs2_dirent_sentinel(dent)) |
392 | actual = GFS2_DIRENT_SIZE(0); | 397 | actual = GFS2_DIRENT_SIZE(0); |
393 | if (totlen - actual >= required) | 398 | if (totlen - actual >= required) |
394 | return 1; | 399 | return 1; |
@@ -405,7 +410,7 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent, | |||
405 | void *opaque) | 410 | void *opaque) |
406 | { | 411 | { |
407 | struct dirent_gather *g = opaque; | 412 | struct dirent_gather *g = opaque; |
408 | if (dent->de_inum.no_addr) { | 413 | if (!gfs2_dirent_sentinel(dent)) { |
409 | g->pdent[g->offset++] = dent; | 414 | g->pdent[g->offset++] = dent; |
410 | } | 415 | } |
411 | return 0; | 416 | return 0; |
@@ -433,10 +438,10 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset, | |||
433 | if (unlikely(offset + size > len)) | 438 | if (unlikely(offset + size > len)) |
434 | goto error; | 439 | goto error; |
435 | msg = "zero inode number"; | 440 | msg = "zero inode number"; |
436 | if (unlikely(!first && !dent->de_inum.no_addr)) | 441 | if (unlikely(!first && gfs2_dirent_sentinel(dent))) |
437 | goto error; | 442 | goto error; |
438 | msg = "name length is greater than space in dirent"; | 443 | msg = "name length is greater than space in dirent"; |
439 | if (dent->de_inum.no_addr && | 444 | if (!gfs2_dirent_sentinel(dent) && |
440 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > | 445 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > |
441 | size)) | 446 | size)) |
442 | goto error; | 447 | goto error; |
@@ -598,7 +603,7 @@ static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh, | |||
598 | return ret; | 603 | return ret; |
599 | 604 | ||
600 | /* Only the first dent could ever have de_inum.no_addr == 0 */ | 605 | /* Only the first dent could ever have de_inum.no_addr == 0 */ |
601 | if (!tmp->de_inum.no_addr) { | 606 | if (gfs2_dirent_sentinel(tmp)) { |
602 | gfs2_consist_inode(dip); | 607 | gfs2_consist_inode(dip); |
603 | return -EIO; | 608 | return -EIO; |
604 | } | 609 | } |
@@ -621,7 +626,7 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
621 | { | 626 | { |
622 | u16 cur_rec_len, prev_rec_len; | 627 | u16 cur_rec_len, prev_rec_len; |
623 | 628 | ||
624 | if (!cur->de_inum.no_addr) { | 629 | if (gfs2_dirent_sentinel(cur)) { |
625 | gfs2_consist_inode(dip); | 630 | gfs2_consist_inode(dip); |
626 | return; | 631 | return; |
627 | } | 632 | } |
@@ -633,7 +638,8 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
633 | out the inode number and return. */ | 638 | out the inode number and return. */ |
634 | 639 | ||
635 | if (!prev) { | 640 | if (!prev) { |
636 | cur->de_inum.no_addr = 0; /* No endianess worries */ | 641 | cur->de_inum.no_addr = 0; |
642 | cur->de_inum.no_formal_ino = 0; | ||
637 | return; | 643 | return; |
638 | } | 644 | } |
639 | 645 | ||
@@ -664,7 +670,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode, | |||
664 | struct gfs2_dirent *ndent; | 670 | struct gfs2_dirent *ndent; |
665 | unsigned offset = 0, totlen; | 671 | unsigned offset = 0, totlen; |
666 | 672 | ||
667 | if (dent->de_inum.no_addr) | 673 | if (!gfs2_dirent_sentinel(dent)) |
668 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 674 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
669 | totlen = be16_to_cpu(dent->de_rec_len); | 675 | totlen = be16_to_cpu(dent->de_rec_len); |
670 | BUG_ON(offset + name->len > totlen); | 676 | BUG_ON(offset + name->len > totlen); |
@@ -713,12 +719,12 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
713 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, | 719 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, |
714 | u64 *leaf_out) | 720 | u64 *leaf_out) |
715 | { | 721 | { |
716 | u64 leaf_no; | 722 | __be64 leaf_no; |
717 | int error; | 723 | int error; |
718 | 724 | ||
719 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, | 725 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, |
720 | index * sizeof(u64), | 726 | index * sizeof(__be64), |
721 | sizeof(u64), 0); | 727 | sizeof(__be64), 0); |
722 | if (error != sizeof(u64)) | 728 | if (error != sizeof(u64)) |
723 | return (error < 0) ? error : -EIO; | 729 | return (error < 0) ? error : -EIO; |
724 | 730 | ||
@@ -837,7 +843,8 @@ static int dir_make_exhash(struct inode *inode) | |||
837 | struct gfs2_leaf *leaf; | 843 | struct gfs2_leaf *leaf; |
838 | int y; | 844 | int y; |
839 | u32 x; | 845 | u32 x; |
840 | u64 *lp, bn; | 846 | __be64 *lp; |
847 | u64 bn; | ||
841 | int error; | 848 | int error; |
842 | 849 | ||
843 | error = gfs2_meta_inode_buffer(dip, &dibh); | 850 | error = gfs2_meta_inode_buffer(dip, &dibh); |
@@ -893,20 +900,20 @@ static int dir_make_exhash(struct inode *inode) | |||
893 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 900 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
894 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 901 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
895 | 902 | ||
896 | lp = (u64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); | 903 | lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); |
897 | 904 | ||
898 | for (x = sdp->sd_hash_ptrs; x--; lp++) | 905 | for (x = sdp->sd_hash_ptrs; x--; lp++) |
899 | *lp = cpu_to_be64(bn); | 906 | *lp = cpu_to_be64(bn); |
900 | 907 | ||
901 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; | 908 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; |
902 | dip->i_di.di_blocks++; | 909 | dip->i_di.di_blocks++; |
910 | gfs2_set_inode_blocks(&dip->i_inode); | ||
903 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; | 911 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; |
904 | dip->i_di.di_payload_format = 0; | ||
905 | 912 | ||
906 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; | 913 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; |
907 | dip->i_di.di_depth = y; | 914 | dip->i_di.di_depth = y; |
908 | 915 | ||
909 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 916 | gfs2_dinode_out(dip, dibh->b_data); |
910 | 917 | ||
911 | brelse(dibh); | 918 | brelse(dibh); |
912 | 919 | ||
@@ -929,7 +936,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
929 | struct gfs2_leaf *nleaf, *oleaf; | 936 | struct gfs2_leaf *nleaf, *oleaf; |
930 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; | 937 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; |
931 | u32 start, len, half_len, divider; | 938 | u32 start, len, half_len, divider; |
932 | u64 bn, *lp, leaf_no; | 939 | u64 bn, leaf_no; |
940 | __be64 *lp; | ||
933 | u32 index; | 941 | u32 index; |
934 | int x, moved = 0; | 942 | int x, moved = 0; |
935 | int error; | 943 | int error; |
@@ -974,7 +982,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
974 | /* Change the pointers. | 982 | /* Change the pointers. |
975 | Don't bother distinguishing stuffed from non-stuffed. | 983 | Don't bother distinguishing stuffed from non-stuffed. |
976 | This code is complicated enough already. */ | 984 | This code is complicated enough already. */ |
977 | lp = kmalloc(half_len * sizeof(u64), GFP_NOFS | __GFP_NOFAIL); | 985 | lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS | __GFP_NOFAIL); |
978 | /* Change the pointers */ | 986 | /* Change the pointers */ |
979 | for (x = 0; x < half_len; x++) | 987 | for (x = 0; x < half_len; x++) |
980 | lp[x] = cpu_to_be64(bn); | 988 | lp[x] = cpu_to_be64(bn); |
@@ -1000,7 +1008,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1000 | if (dirent_next(dip, obh, &next)) | 1008 | if (dirent_next(dip, obh, &next)) |
1001 | next = NULL; | 1009 | next = NULL; |
1002 | 1010 | ||
1003 | if (dent->de_inum.no_addr && | 1011 | if (!gfs2_dirent_sentinel(dent) && |
1004 | be32_to_cpu(dent->de_hash) < divider) { | 1012 | be32_to_cpu(dent->de_hash) < divider) { |
1005 | struct qstr str; | 1013 | struct qstr str; |
1006 | str.name = (char*)(dent+1); | 1014 | str.name = (char*)(dent+1); |
@@ -1037,7 +1045,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1037 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1045 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1038 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { | 1046 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { |
1039 | dip->i_di.di_blocks++; | 1047 | dip->i_di.di_blocks++; |
1040 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1048 | gfs2_set_inode_blocks(&dip->i_inode); |
1049 | gfs2_dinode_out(dip, dibh->b_data); | ||
1041 | brelse(dibh); | 1050 | brelse(dibh); |
1042 | } | 1051 | } |
1043 | 1052 | ||
@@ -1117,7 +1126,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1117 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1126 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1118 | if (!gfs2_assert_withdraw(sdp, !error)) { | 1127 | if (!gfs2_assert_withdraw(sdp, !error)) { |
1119 | dip->i_di.di_depth++; | 1128 | dip->i_di.di_depth++; |
1120 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1129 | gfs2_dinode_out(dip, dibh->b_data); |
1121 | brelse(dibh); | 1130 | brelse(dibh); |
1122 | } | 1131 | } |
1123 | 1132 | ||
@@ -1194,7 +1203,7 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1194 | int *copied) | 1203 | int *copied) |
1195 | { | 1204 | { |
1196 | const struct gfs2_dirent *dent, *dent_next; | 1205 | const struct gfs2_dirent *dent, *dent_next; |
1197 | struct gfs2_inum inum; | 1206 | struct gfs2_inum_host inum; |
1198 | u64 off, off_next; | 1207 | u64 off, off_next; |
1199 | unsigned int x, y; | 1208 | unsigned int x, y; |
1200 | int run = 0; | 1209 | int run = 0; |
@@ -1341,7 +1350,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1341 | u32 hsize, len = 0; | 1350 | u32 hsize, len = 0; |
1342 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1351 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1343 | u32 hash, index; | 1352 | u32 hash, index; |
1344 | u64 *lp; | 1353 | __be64 *lp; |
1345 | int copied = 0; | 1354 | int copied = 0; |
1346 | int error = 0; | 1355 | int error = 0; |
1347 | unsigned depth = 0; | 1356 | unsigned depth = 0; |
@@ -1365,7 +1374,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1365 | 1374 | ||
1366 | if (ht_offset_cur != ht_offset) { | 1375 | if (ht_offset_cur != ht_offset) { |
1367 | error = gfs2_dir_read_data(dip, (char *)lp, | 1376 | error = gfs2_dir_read_data(dip, (char *)lp, |
1368 | ht_offset * sizeof(u64), | 1377 | ht_offset * sizeof(__be64), |
1369 | sdp->sd_hash_bsize, 1); | 1378 | sdp->sd_hash_bsize, 1); |
1370 | if (error != sdp->sd_hash_bsize) { | 1379 | if (error != sdp->sd_hash_bsize) { |
1371 | if (error >= 0) | 1380 | if (error >= 0) |
@@ -1456,7 +1465,7 @@ out: | |||
1456 | */ | 1465 | */ |
1457 | 1466 | ||
1458 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, | 1467 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, |
1459 | struct gfs2_inum *inum, unsigned int *type) | 1468 | struct gfs2_inum_host *inum, unsigned int *type) |
1460 | { | 1469 | { |
1461 | struct buffer_head *bh; | 1470 | struct buffer_head *bh; |
1462 | struct gfs2_dirent *dent; | 1471 | struct gfs2_dirent *dent; |
@@ -1515,7 +1524,8 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1515 | return error; | 1524 | return error; |
1516 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1525 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1517 | ip->i_di.di_blocks++; | 1526 | ip->i_di.di_blocks++; |
1518 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1527 | gfs2_set_inode_blocks(&ip->i_inode); |
1528 | gfs2_dinode_out(ip, bh->b_data); | ||
1519 | brelse(bh); | 1529 | brelse(bh); |
1520 | return 0; | 1530 | return 0; |
1521 | } | 1531 | } |
@@ -1531,7 +1541,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1531 | */ | 1541 | */ |
1532 | 1542 | ||
1533 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1543 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1534 | const struct gfs2_inum *inum, unsigned type) | 1544 | const struct gfs2_inum_host *inum, unsigned type) |
1535 | { | 1545 | { |
1536 | struct gfs2_inode *ip = GFS2_I(inode); | 1546 | struct gfs2_inode *ip = GFS2_I(inode); |
1537 | struct buffer_head *bh; | 1547 | struct buffer_head *bh; |
@@ -1558,8 +1568,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1558 | break; | 1568 | break; |
1559 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1569 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1560 | ip->i_di.di_entries++; | 1570 | ip->i_di.di_entries++; |
1561 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1571 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1562 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1572 | gfs2_dinode_out(ip, bh->b_data); |
1563 | brelse(bh); | 1573 | brelse(bh); |
1564 | error = 0; | 1574 | error = 0; |
1565 | break; | 1575 | break; |
@@ -1644,8 +1654,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1644 | gfs2_consist_inode(dip); | 1654 | gfs2_consist_inode(dip); |
1645 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1655 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1646 | dip->i_di.di_entries--; | 1656 | dip->i_di.di_entries--; |
1647 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1657 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1648 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1658 | gfs2_dinode_out(dip, bh->b_data); |
1649 | brelse(bh); | 1659 | brelse(bh); |
1650 | mark_inode_dirty(&dip->i_inode); | 1660 | mark_inode_dirty(&dip->i_inode); |
1651 | 1661 | ||
@@ -1666,7 +1676,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1666 | */ | 1676 | */ |
1667 | 1677 | ||
1668 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 1678 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
1669 | struct gfs2_inum *inum, unsigned int new_type) | 1679 | struct gfs2_inum_host *inum, unsigned int new_type) |
1670 | { | 1680 | { |
1671 | struct buffer_head *bh; | 1681 | struct buffer_head *bh; |
1672 | struct gfs2_dirent *dent; | 1682 | struct gfs2_dirent *dent; |
@@ -1692,8 +1702,8 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1692 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1702 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1693 | } | 1703 | } |
1694 | 1704 | ||
1695 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1705 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1696 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1706 | gfs2_dinode_out(dip, bh->b_data); |
1697 | brelse(bh); | 1707 | brelse(bh); |
1698 | return 0; | 1708 | return 0; |
1699 | } | 1709 | } |
@@ -1715,7 +1725,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1715 | u32 hsize, len; | 1725 | u32 hsize, len; |
1716 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1726 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1717 | u32 index = 0; | 1727 | u32 index = 0; |
1718 | u64 *lp; | 1728 | __be64 *lp; |
1719 | u64 leaf_no; | 1729 | u64 leaf_no; |
1720 | int error = 0; | 1730 | int error = 0; |
1721 | 1731 | ||
@@ -1735,7 +1745,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1735 | 1745 | ||
1736 | if (ht_offset_cur != ht_offset) { | 1746 | if (ht_offset_cur != ht_offset) { |
1737 | error = gfs2_dir_read_data(dip, (char *)lp, | 1747 | error = gfs2_dir_read_data(dip, (char *)lp, |
1738 | ht_offset * sizeof(u64), | 1748 | ht_offset * sizeof(__be64), |
1739 | sdp->sd_hash_bsize, 1); | 1749 | sdp->sd_hash_bsize, 1); |
1740 | if (error != sdp->sd_hash_bsize) { | 1750 | if (error != sdp->sd_hash_bsize) { |
1741 | if (error >= 0) | 1751 | if (error >= 0) |
@@ -1859,6 +1869,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1859 | if (!dip->i_di.di_blocks) | 1869 | if (!dip->i_di.di_blocks) |
1860 | gfs2_consist_inode(dip); | 1870 | gfs2_consist_inode(dip); |
1861 | dip->i_di.di_blocks--; | 1871 | dip->i_di.di_blocks--; |
1872 | gfs2_set_inode_blocks(&dip->i_inode); | ||
1862 | } | 1873 | } |
1863 | 1874 | ||
1864 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); | 1875 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); |
@@ -1873,7 +1884,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1873 | goto out_end_trans; | 1884 | goto out_end_trans; |
1874 | 1885 | ||
1875 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 1886 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
1876 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1887 | gfs2_dinode_out(dip, dibh->b_data); |
1877 | brelse(dibh); | 1888 | brelse(dibh); |
1878 | 1889 | ||
1879 | out_end_trans: | 1890 | out_end_trans: |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 371233419b07..b21b33668a5b 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -31,17 +31,17 @@ struct gfs2_inum; | |||
31 | typedef int (*gfs2_filldir_t) (void *opaque, | 31 | typedef int (*gfs2_filldir_t) (void *opaque, |
32 | const char *name, unsigned int length, | 32 | const char *name, unsigned int length, |
33 | u64 offset, | 33 | u64 offset, |
34 | struct gfs2_inum *inum, unsigned int type); | 34 | struct gfs2_inum_host *inum, unsigned int type); |
35 | 35 | ||
36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, | 36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, |
37 | struct gfs2_inum *inum, unsigned int *type); | 37 | struct gfs2_inum_host *inum, unsigned int *type); |
38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
39 | const struct gfs2_inum *inum, unsigned int type); | 39 | const struct gfs2_inum_host *inum, unsigned int type); |
40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); | 40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); |
41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, | 41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, |
42 | gfs2_filldir_t filldir); | 42 | gfs2_filldir_t filldir); |
43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
44 | struct gfs2_inum *new_inum, unsigned int new_type); | 44 | struct gfs2_inum_host *new_inum, unsigned int new_type); |
45 | 45 | ||
46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); | 46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); |
47 | 47 | ||
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c index 92c54e9b0dc3..cd747c00f670 100644 --- a/fs/gfs2/eaops.c +++ b/fs/gfs2/eaops.c | |||
@@ -120,7 +120,7 @@ static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
120 | 120 | ||
121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { | 121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { |
122 | if (!(er->er_flags & GFS2_ERF_MODE)) { | 122 | if (!(er->er_flags & GFS2_ERF_MODE)) { |
123 | er->er_mode = ip->i_di.di_mode; | 123 | er->er_mode = ip->i_inode.i_mode; |
124 | er->er_flags |= GFS2_ERF_MODE; | 124 | er->er_flags |= GFS2_ERF_MODE; |
125 | } | 125 | } |
126 | error = gfs2_acl_validate_set(ip, 1, er, | 126 | error = gfs2_acl_validate_set(ip, 1, er, |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index a65a4ccfd4dd..ebebbdcd7057 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -112,7 +112,7 @@ fail: | |||
112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | 112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) |
113 | { | 113 | { |
114 | struct buffer_head *bh, *eabh; | 114 | struct buffer_head *bh, *eabh; |
115 | u64 *eablk, *end; | 115 | __be64 *eablk, *end; |
116 | int error; | 116 | int error; |
117 | 117 | ||
118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); | 118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); |
@@ -129,7 +129,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
129 | goto out; | 129 | goto out; |
130 | } | 130 | } |
131 | 131 | ||
132 | eablk = (u64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); | 132 | eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); |
133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; | 133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; |
134 | 134 | ||
135 | for (; eablk < end; eablk++) { | 135 | for (; eablk < end; eablk++) { |
@@ -224,7 +224,8 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
224 | struct gfs2_rgrpd *rgd; | 224 | struct gfs2_rgrpd *rgd; |
225 | struct gfs2_holder rg_gh; | 225 | struct gfs2_holder rg_gh; |
226 | struct buffer_head *dibh; | 226 | struct buffer_head *dibh; |
227 | u64 *dataptrs, bn = 0; | 227 | __be64 *dataptrs; |
228 | u64 bn = 0; | ||
228 | u64 bstart = 0; | 229 | u64 bstart = 0; |
229 | unsigned int blen = 0; | 230 | unsigned int blen = 0; |
230 | unsigned int blks = 0; | 231 | unsigned int blks = 0; |
@@ -280,6 +281,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
280 | if (!ip->i_di.di_blocks) | 281 | if (!ip->i_di.di_blocks) |
281 | gfs2_consist_inode(ip); | 282 | gfs2_consist_inode(ip); |
282 | ip->i_di.di_blocks--; | 283 | ip->i_di.di_blocks--; |
284 | gfs2_set_inode_blocks(&ip->i_inode); | ||
283 | } | 285 | } |
284 | if (bstart) | 286 | if (bstart) |
285 | gfs2_free_meta(ip, bstart, blen); | 287 | gfs2_free_meta(ip, bstart, blen); |
@@ -299,9 +301,9 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
299 | 301 | ||
300 | error = gfs2_meta_inode_buffer(ip, &dibh); | 302 | error = gfs2_meta_inode_buffer(ip, &dibh); |
301 | if (!error) { | 303 | if (!error) { |
302 | ip->i_di.di_ctime = get_seconds(); | 304 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
303 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 305 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
304 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 306 | gfs2_dinode_out(ip, dibh->b_data); |
305 | brelse(dibh); | 307 | brelse(dibh); |
306 | } | 308 | } |
307 | 309 | ||
@@ -444,7 +446,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
444 | struct buffer_head **bh; | 446 | struct buffer_head **bh; |
445 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 447 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
446 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 448 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
447 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 449 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
448 | unsigned int x; | 450 | unsigned int x; |
449 | int error = 0; | 451 | int error = 0; |
450 | 452 | ||
@@ -597,6 +599,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) | |||
597 | ea->ea_num_ptrs = 0; | 599 | ea->ea_num_ptrs = 0; |
598 | 600 | ||
599 | ip->i_di.di_blocks++; | 601 | ip->i_di.di_blocks++; |
602 | gfs2_set_inode_blocks(&ip->i_inode); | ||
600 | 603 | ||
601 | return 0; | 604 | return 0; |
602 | } | 605 | } |
@@ -629,7 +632,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
629 | ea->ea_num_ptrs = 0; | 632 | ea->ea_num_ptrs = 0; |
630 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); | 633 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); |
631 | } else { | 634 | } else { |
632 | u64 *dataptr = GFS2_EA2DATAPTRS(ea); | 635 | __be64 *dataptr = GFS2_EA2DATAPTRS(ea); |
633 | const char *data = er->er_data; | 636 | const char *data = er->er_data; |
634 | unsigned int data_len = er->er_data_len; | 637 | unsigned int data_len = er->er_data_len; |
635 | unsigned int copy; | 638 | unsigned int copy; |
@@ -648,6 +651,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
648 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); | 651 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); |
649 | 652 | ||
650 | ip->i_di.di_blocks++; | 653 | ip->i_di.di_blocks++; |
654 | gfs2_set_inode_blocks(&ip->i_inode); | ||
651 | 655 | ||
652 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : | 656 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : |
653 | data_len; | 657 | data_len; |
@@ -686,7 +690,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
686 | if (error) | 690 | if (error) |
687 | goto out; | 691 | goto out; |
688 | 692 | ||
689 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 693 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
690 | if (error) | 694 | if (error) |
691 | goto out_gunlock_q; | 695 | goto out_gunlock_q; |
692 | 696 | ||
@@ -710,13 +714,13 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
710 | if (!error) { | 714 | if (!error) { |
711 | if (er->er_flags & GFS2_ERF_MODE) { | 715 | if (er->er_flags & GFS2_ERF_MODE) { |
712 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 716 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
713 | (ip->i_di.di_mode & S_IFMT) == | 717 | (ip->i_inode.i_mode & S_IFMT) == |
714 | (er->er_mode & S_IFMT)); | 718 | (er->er_mode & S_IFMT)); |
715 | ip->i_di.di_mode = er->er_mode; | 719 | ip->i_inode.i_mode = er->er_mode; |
716 | } | 720 | } |
717 | ip->i_di.di_ctime = get_seconds(); | 721 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
718 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 722 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
719 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 723 | gfs2_dinode_out(ip, dibh->b_data); |
720 | brelse(dibh); | 724 | brelse(dibh); |
721 | } | 725 | } |
722 | 726 | ||
@@ -846,12 +850,12 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh, | |||
846 | 850 | ||
847 | if (er->er_flags & GFS2_ERF_MODE) { | 851 | if (er->er_flags & GFS2_ERF_MODE) { |
848 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 852 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
849 | (ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT)); | 853 | (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); |
850 | ip->i_di.di_mode = er->er_mode; | 854 | ip->i_inode.i_mode = er->er_mode; |
851 | } | 855 | } |
852 | ip->i_di.di_ctime = get_seconds(); | 856 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
853 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
854 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
855 | brelse(dibh); | 859 | brelse(dibh); |
856 | out: | 860 | out: |
857 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 861 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); |
@@ -931,12 +935,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
931 | { | 935 | { |
932 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 936 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
933 | struct buffer_head *indbh, *newbh; | 937 | struct buffer_head *indbh, *newbh; |
934 | u64 *eablk; | 938 | __be64 *eablk; |
935 | int error; | 939 | int error; |
936 | int mh_size = sizeof(struct gfs2_meta_header); | 940 | int mh_size = sizeof(struct gfs2_meta_header); |
937 | 941 | ||
938 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { | 942 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { |
939 | u64 *end; | 943 | __be64 *end; |
940 | 944 | ||
941 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, | 945 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, |
942 | &indbh); | 946 | &indbh); |
@@ -948,7 +952,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
948 | goto out; | 952 | goto out; |
949 | } | 953 | } |
950 | 954 | ||
951 | eablk = (u64 *)(indbh->b_data + mh_size); | 955 | eablk = (__be64 *)(indbh->b_data + mh_size); |
952 | end = eablk + sdp->sd_inptrs; | 956 | end = eablk + sdp->sd_inptrs; |
953 | 957 | ||
954 | for (; eablk < end; eablk++) | 958 | for (; eablk < end; eablk++) |
@@ -971,11 +975,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
971 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 975 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
972 | gfs2_buffer_clear_tail(indbh, mh_size); | 976 | gfs2_buffer_clear_tail(indbh, mh_size); |
973 | 977 | ||
974 | eablk = (u64 *)(indbh->b_data + mh_size); | 978 | eablk = (__be64 *)(indbh->b_data + mh_size); |
975 | *eablk = cpu_to_be64(ip->i_di.di_eattr); | 979 | *eablk = cpu_to_be64(ip->i_di.di_eattr); |
976 | ip->i_di.di_eattr = blk; | 980 | ip->i_di.di_eattr = blk; |
977 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; | 981 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; |
978 | ip->i_di.di_blocks++; | 982 | ip->i_di.di_blocks++; |
983 | gfs2_set_inode_blocks(&ip->i_inode); | ||
979 | 984 | ||
980 | eablk++; | 985 | eablk++; |
981 | } | 986 | } |
@@ -1129,9 +1134,9 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el) | |||
1129 | 1134 | ||
1130 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1135 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1131 | if (!error) { | 1136 | if (!error) { |
1132 | ip->i_di.di_ctime = get_seconds(); | 1137 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1133 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1138 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1134 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1139 | gfs2_dinode_out(ip, dibh->b_data); |
1135 | brelse(dibh); | 1140 | brelse(dibh); |
1136 | } | 1141 | } |
1137 | 1142 | ||
@@ -1202,7 +1207,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, | |||
1202 | struct buffer_head **bh; | 1207 | struct buffer_head **bh; |
1203 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 1208 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
1204 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 1209 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
1205 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 1210 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
1206 | unsigned int x; | 1211 | unsigned int x; |
1207 | int error; | 1212 | int error; |
1208 | 1213 | ||
@@ -1284,9 +1289,8 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, | |||
1284 | if (!error) { | 1289 | if (!error) { |
1285 | error = inode_setattr(&ip->i_inode, attr); | 1290 | error = inode_setattr(&ip->i_inode, attr); |
1286 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1291 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1287 | gfs2_inode_attr_out(ip); | ||
1288 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1292 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1289 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1293 | gfs2_dinode_out(ip, dibh->b_data); |
1290 | brelse(dibh); | 1294 | brelse(dibh); |
1291 | } | 1295 | } |
1292 | 1296 | ||
@@ -1300,7 +1304,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1300 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1304 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1301 | struct gfs2_rgrp_list rlist; | 1305 | struct gfs2_rgrp_list rlist; |
1302 | struct buffer_head *indbh, *dibh; | 1306 | struct buffer_head *indbh, *dibh; |
1303 | u64 *eablk, *end; | 1307 | __be64 *eablk, *end; |
1304 | unsigned int rg_blocks = 0; | 1308 | unsigned int rg_blocks = 0; |
1305 | u64 bstart = 0; | 1309 | u64 bstart = 0; |
1306 | unsigned int blen = 0; | 1310 | unsigned int blen = 0; |
@@ -1319,7 +1323,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1319 | goto out; | 1323 | goto out; |
1320 | } | 1324 | } |
1321 | 1325 | ||
1322 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1326 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1323 | end = eablk + sdp->sd_inptrs; | 1327 | end = eablk + sdp->sd_inptrs; |
1324 | 1328 | ||
1325 | for (; eablk < end; eablk++) { | 1329 | for (; eablk < end; eablk++) { |
@@ -1363,7 +1367,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1363 | 1367 | ||
1364 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); | 1368 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); |
1365 | 1369 | ||
1366 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1370 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1367 | bstart = 0; | 1371 | bstart = 0; |
1368 | blen = 0; | 1372 | blen = 0; |
1369 | 1373 | ||
@@ -1387,6 +1391,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1387 | if (!ip->i_di.di_blocks) | 1391 | if (!ip->i_di.di_blocks) |
1388 | gfs2_consist_inode(ip); | 1392 | gfs2_consist_inode(ip); |
1389 | ip->i_di.di_blocks--; | 1393 | ip->i_di.di_blocks--; |
1394 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1390 | } | 1395 | } |
1391 | if (bstart) | 1396 | if (bstart) |
1392 | gfs2_free_meta(ip, bstart, blen); | 1397 | gfs2_free_meta(ip, bstart, blen); |
@@ -1396,7 +1401,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1401 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1397 | if (!error) { | 1402 | if (!error) { |
1398 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1403 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1399 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1404 | gfs2_dinode_out(ip, dibh->b_data); |
1400 | brelse(dibh); | 1405 | brelse(dibh); |
1401 | } | 1406 | } |
1402 | 1407 | ||
@@ -1441,11 +1446,12 @@ static int ea_dealloc_block(struct gfs2_inode *ip) | |||
1441 | if (!ip->i_di.di_blocks) | 1446 | if (!ip->i_di.di_blocks) |
1442 | gfs2_consist_inode(ip); | 1447 | gfs2_consist_inode(ip); |
1443 | ip->i_di.di_blocks--; | 1448 | ip->i_di.di_blocks--; |
1449 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1444 | 1450 | ||
1445 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1451 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1446 | if (!error) { | 1452 | if (!error) { |
1447 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1453 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1448 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1454 | gfs2_dinode_out(ip, dibh->b_data); |
1449 | brelse(dibh); | 1455 | brelse(dibh); |
1450 | } | 1456 | } |
1451 | 1457 | ||
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h index ffa65947d686..c82dbe01d713 100644 --- a/fs/gfs2/eattr.h +++ b/fs/gfs2/eattr.h | |||
@@ -19,7 +19,7 @@ struct iattr; | |||
19 | #define GFS2_EA_SIZE(ea) \ | 19 | #define GFS2_EA_SIZE(ea) \ |
20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ | 20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ |
21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ | 21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ |
22 | (sizeof(u64) * (ea)->ea_num_ptrs)), 8) | 22 | (sizeof(__be64) * (ea)->ea_num_ptrs)), 8) |
23 | 23 | ||
24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) | 24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) |
25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) | 25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) |
@@ -29,13 +29,13 @@ ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8) | |||
29 | 29 | ||
30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ | 30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ |
31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ | 31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ |
32 | sizeof(u64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) | 32 | sizeof(__be64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) |
33 | 33 | ||
34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) | 34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) |
35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) | 35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) |
36 | 36 | ||
37 | #define GFS2_EA2DATAPTRS(ea) \ | 37 | #define GFS2_EA2DATAPTRS(ea) \ |
38 | ((u64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) | 38 | ((__be64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) |
39 | 39 | ||
40 | #define GFS2_EA2NEXT(ea) \ | 40 | #define GFS2_EA2NEXT(ea) \ |
41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) | 41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 78fe0fae23ff..438146904b58 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | struct greedy { | 36 | struct greedy { |
37 | struct gfs2_holder gr_gh; | 37 | struct gfs2_holder gr_gh; |
38 | struct work_struct gr_work; | 38 | struct delayed_work gr_work; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct gfs2_gl_hash_bucket { | 41 | struct gfs2_gl_hash_bucket { |
@@ -96,7 +96,7 @@ static inline rwlock_t *gl_lock_addr(unsigned int x) | |||
96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; | 96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; |
97 | } | 97 | } |
98 | #else /* not SMP, so no spinlocks required */ | 98 | #else /* not SMP, so no spinlocks required */ |
99 | static inline rwlock_t *gl_lock_addr(x) | 99 | static inline rwlock_t *gl_lock_addr(unsigned int x) |
100 | { | 100 | { |
101 | return NULL; | 101 | return NULL; |
102 | } | 102 | } |
@@ -769,7 +769,7 @@ restart: | |||
769 | } else { | 769 | } else { |
770 | spin_unlock(&gl->gl_spin); | 770 | spin_unlock(&gl->gl_spin); |
771 | 771 | ||
772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_KERNEL); | 772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_NOFS); |
773 | if (!new_gh) | 773 | if (!new_gh) |
774 | return; | 774 | return; |
775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); | 775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); |
@@ -785,21 +785,6 @@ out: | |||
785 | gfs2_holder_put(new_gh); | 785 | gfs2_holder_put(new_gh); |
786 | } | 786 | } |
787 | 787 | ||
788 | void gfs2_glock_inode_squish(struct inode *inode) | ||
789 | { | ||
790 | struct gfs2_holder gh; | ||
791 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | ||
792 | gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); | ||
793 | set_bit(HIF_DEMOTE, &gh.gh_iflags); | ||
794 | spin_lock(&gl->gl_spin); | ||
795 | gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders)); | ||
796 | list_add_tail(&gh.gh_list, &gl->gl_waiters2); | ||
797 | run_queue(gl); | ||
798 | spin_unlock(&gl->gl_spin); | ||
799 | wait_for_completion(&gh.gh_wait); | ||
800 | gfs2_holder_uninit(&gh); | ||
801 | } | ||
802 | |||
803 | /** | 788 | /** |
804 | * state_change - record that the glock is now in a different state | 789 | * state_change - record that the glock is now in a different state |
805 | * @gl: the glock | 790 | * @gl: the glock |
@@ -847,12 +832,12 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
847 | 832 | ||
848 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { | 833 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { |
849 | if (glops->go_inval) | 834 | if (glops->go_inval) |
850 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 835 | glops->go_inval(gl, DIO_METADATA); |
851 | } else if (gl->gl_state == LM_ST_DEFERRED) { | 836 | } else if (gl->gl_state == LM_ST_DEFERRED) { |
852 | /* We might not want to do this here. | 837 | /* We might not want to do this here. |
853 | Look at moving to the inode glops. */ | 838 | Look at moving to the inode glops. */ |
854 | if (glops->go_inval) | 839 | if (glops->go_inval) |
855 | glops->go_inval(gl, DIO_DATA); | 840 | glops->go_inval(gl, 0); |
856 | } | 841 | } |
857 | 842 | ||
858 | /* Deal with each possible exit condition */ | 843 | /* Deal with each possible exit condition */ |
@@ -954,7 +939,7 @@ void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags) | |||
954 | gfs2_assert_warn(sdp, state != gl->gl_state); | 939 | gfs2_assert_warn(sdp, state != gl->gl_state); |
955 | 940 | ||
956 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 941 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
957 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 942 | glops->go_sync(gl); |
958 | 943 | ||
959 | gfs2_glock_hold(gl); | 944 | gfs2_glock_hold(gl); |
960 | gl->gl_req_bh = xmote_bh; | 945 | gl->gl_req_bh = xmote_bh; |
@@ -995,7 +980,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
995 | state_change(gl, LM_ST_UNLOCKED); | 980 | state_change(gl, LM_ST_UNLOCKED); |
996 | 981 | ||
997 | if (glops->go_inval) | 982 | if (glops->go_inval) |
998 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 983 | glops->go_inval(gl, DIO_METADATA); |
999 | 984 | ||
1000 | if (gh) { | 985 | if (gh) { |
1001 | spin_lock(&gl->gl_spin); | 986 | spin_lock(&gl->gl_spin); |
@@ -1041,7 +1026,7 @@ void gfs2_glock_drop_th(struct gfs2_glock *gl) | |||
1041 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); | 1026 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); |
1042 | 1027 | ||
1043 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 1028 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
1044 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 1029 | glops->go_sync(gl); |
1045 | 1030 | ||
1046 | gfs2_glock_hold(gl); | 1031 | gfs2_glock_hold(gl); |
1047 | gl->gl_req_bh = drop_bh; | 1032 | gl->gl_req_bh = drop_bh; |
@@ -1244,9 +1229,6 @@ restart: | |||
1244 | 1229 | ||
1245 | clear_bit(GLF_PREFETCH, &gl->gl_flags); | 1230 | clear_bit(GLF_PREFETCH, &gl->gl_flags); |
1246 | 1231 | ||
1247 | if (error == GLR_TRYFAILED && (gh->gh_flags & GL_DUMP)) | ||
1248 | dump_glock(gl); | ||
1249 | |||
1250 | return error; | 1232 | return error; |
1251 | } | 1233 | } |
1252 | 1234 | ||
@@ -1368,9 +1350,9 @@ static void gfs2_glock_prefetch(struct gfs2_glock *gl, unsigned int state, | |||
1368 | glops->go_xmote_th(gl, state, flags); | 1350 | glops->go_xmote_th(gl, state, flags); |
1369 | } | 1351 | } |
1370 | 1352 | ||
1371 | static void greedy_work(void *data) | 1353 | static void greedy_work(struct work_struct *work) |
1372 | { | 1354 | { |
1373 | struct greedy *gr = data; | 1355 | struct greedy *gr = container_of(work, struct greedy, gr_work.work); |
1374 | struct gfs2_holder *gh = &gr->gr_gh; | 1356 | struct gfs2_holder *gh = &gr->gr_gh; |
1375 | struct gfs2_glock *gl = gh->gh_gl; | 1357 | struct gfs2_glock *gl = gh->gh_gl; |
1376 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1358 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
@@ -1422,7 +1404,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time) | |||
1422 | 1404 | ||
1423 | gfs2_holder_init(gl, 0, 0, gh); | 1405 | gfs2_holder_init(gl, 0, 0, gh); |
1424 | set_bit(HIF_GREEDY, &gh->gh_iflags); | 1406 | set_bit(HIF_GREEDY, &gh->gh_iflags); |
1425 | INIT_WORK(&gr->gr_work, greedy_work, gr); | 1407 | INIT_DELAYED_WORK(&gr->gr_work, greedy_work); |
1426 | 1408 | ||
1427 | set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); | 1409 | set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); |
1428 | schedule_delayed_work(&gr->gr_work, time); | 1410 | schedule_delayed_work(&gr->gr_work, time); |
@@ -1923,7 +1905,7 @@ out: | |||
1923 | 1905 | ||
1924 | static void scan_glock(struct gfs2_glock *gl) | 1906 | static void scan_glock(struct gfs2_glock *gl) |
1925 | { | 1907 | { |
1926 | if (gl->gl_ops == &gfs2_inode_glops) | 1908 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) |
1927 | return; | 1909 | return; |
1928 | 1910 | ||
1929 | if (gfs2_glmutex_trylock(gl)) { | 1911 | if (gfs2_glmutex_trylock(gl)) { |
@@ -2078,7 +2060,7 @@ static int dump_inode(struct gfs2_inode *ip) | |||
2078 | printk(KERN_INFO " num = %llu %llu\n", | 2060 | printk(KERN_INFO " num = %llu %llu\n", |
2079 | (unsigned long long)ip->i_num.no_formal_ino, | 2061 | (unsigned long long)ip->i_num.no_formal_ino, |
2080 | (unsigned long long)ip->i_num.no_addr); | 2062 | (unsigned long long)ip->i_num.no_addr); |
2081 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode)); | 2063 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode)); |
2082 | printk(KERN_INFO " i_flags ="); | 2064 | printk(KERN_INFO " i_flags ="); |
2083 | for (x = 0; x < 32; x++) | 2065 | for (x = 0; x < 32; x++) |
2084 | if (test_bit(x, &ip->i_flags)) | 2066 | if (test_bit(x, &ip->i_flags)) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 2b2a889ee2cc..fb39108fc05c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #define GL_ATIME 0x00000200 | 27 | #define GL_ATIME 0x00000200 |
28 | #define GL_NOCACHE 0x00000400 | 28 | #define GL_NOCACHE 0x00000400 |
29 | #define GL_NOCANCEL 0x00001000 | 29 | #define GL_NOCANCEL 0x00001000 |
30 | #define GL_AOP 0x00004000 | ||
31 | #define GL_DUMP 0x00008000 | ||
32 | 30 | ||
33 | #define GLR_TRYFAILED 13 | 31 | #define GLR_TRYFAILED 13 |
34 | #define GLR_CANCELED 14 | 32 | #define GLR_CANCELED 14 |
@@ -108,7 +106,6 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); | |||
108 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, | 106 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, |
109 | const struct gfs2_glock_operations *glops, | 107 | const struct gfs2_glock_operations *glops, |
110 | unsigned int state, int flags); | 108 | unsigned int state, int flags); |
111 | void gfs2_glock_inode_squish(struct inode *inode); | ||
112 | 109 | ||
113 | /** | 110 | /** |
114 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock | 111 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 41a6b6818a50..b068d10bcb6e 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -92,7 +92,7 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
92 | 92 | ||
93 | ip = gl->gl_object; | 93 | ip = gl->gl_object; |
94 | inode = &ip->i_inode; | 94 | inode = &ip->i_inode; |
95 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | 95 | if (!ip || !S_ISREG(inode->i_mode)) |
96 | return; | 96 | return; |
97 | 97 | ||
98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) | 98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) |
@@ -107,89 +107,20 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * gfs2_page_inval - Invalidate all pages associated with a glock | ||
111 | * @gl: the glock | ||
112 | * | ||
113 | */ | ||
114 | |||
115 | static void gfs2_page_inval(struct gfs2_glock *gl) | ||
116 | { | ||
117 | struct gfs2_inode *ip; | ||
118 | struct inode *inode; | ||
119 | |||
120 | ip = gl->gl_object; | ||
121 | inode = &ip->i_inode; | ||
122 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | ||
123 | return; | ||
124 | |||
125 | truncate_inode_pages(inode->i_mapping, 0); | ||
126 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages); | ||
127 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * gfs2_page_wait - Wait for writeback of data | ||
132 | * @gl: the glock | ||
133 | * | ||
134 | * Syncs data (not metadata) for a regular file. | ||
135 | * No-op for all other types. | ||
136 | */ | ||
137 | |||
138 | static void gfs2_page_wait(struct gfs2_glock *gl) | ||
139 | { | ||
140 | struct gfs2_inode *ip = gl->gl_object; | ||
141 | struct inode *inode = &ip->i_inode; | ||
142 | struct address_space *mapping = inode->i_mapping; | ||
143 | int error; | ||
144 | |||
145 | if (!S_ISREG(ip->i_di.di_mode)) | ||
146 | return; | ||
147 | |||
148 | error = filemap_fdatawait(mapping); | ||
149 | |||
150 | /* Put back any errors cleared by filemap_fdatawait() | ||
151 | so they can be caught by someone who can pass them | ||
152 | up to user space. */ | ||
153 | |||
154 | if (error == -ENOSPC) | ||
155 | set_bit(AS_ENOSPC, &mapping->flags); | ||
156 | else if (error) | ||
157 | set_bit(AS_EIO, &mapping->flags); | ||
158 | |||
159 | } | ||
160 | |||
161 | static void gfs2_page_writeback(struct gfs2_glock *gl) | ||
162 | { | ||
163 | struct gfs2_inode *ip = gl->gl_object; | ||
164 | struct inode *inode = &ip->i_inode; | ||
165 | struct address_space *mapping = inode->i_mapping; | ||
166 | |||
167 | if (!S_ISREG(ip->i_di.di_mode)) | ||
168 | return; | ||
169 | |||
170 | filemap_fdatawrite(mapping); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * meta_go_sync - sync out the metadata for this glock | 110 | * meta_go_sync - sync out the metadata for this glock |
175 | * @gl: the glock | 111 | * @gl: the glock |
176 | * @flags: DIO_* | ||
177 | * | 112 | * |
178 | * Called when demoting or unlocking an EX glock. We must flush | 113 | * Called when demoting or unlocking an EX glock. We must flush |
179 | * to disk all dirty buffers/pages relating to this glock, and must not | 114 | * to disk all dirty buffers/pages relating to this glock, and must not |
180 | * not return to caller to demote/unlock the glock until I/O is complete. | 115 | * not return to caller to demote/unlock the glock until I/O is complete. |
181 | */ | 116 | */ |
182 | 117 | ||
183 | static void meta_go_sync(struct gfs2_glock *gl, int flags) | 118 | static void meta_go_sync(struct gfs2_glock *gl) |
184 | { | 119 | { |
185 | if (!(flags & DIO_METADATA)) | ||
186 | return; | ||
187 | |||
188 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { | 120 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { |
189 | gfs2_log_flush(gl->gl_sbd, gl); | 121 | gfs2_log_flush(gl->gl_sbd, gl); |
190 | gfs2_meta_sync(gl); | 122 | gfs2_meta_sync(gl); |
191 | if (flags & DIO_RELEASE) | 123 | gfs2_ail_empty_gl(gl); |
192 | gfs2_ail_empty_gl(gl); | ||
193 | } | 124 | } |
194 | 125 | ||
195 | } | 126 | } |
@@ -264,31 +195,31 @@ static void inode_go_drop_th(struct gfs2_glock *gl) | |||
264 | /** | 195 | /** |
265 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock | 196 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock |
266 | * @gl: the glock protecting the inode | 197 | * @gl: the glock protecting the inode |
267 | * @flags: | ||
268 | * | 198 | * |
269 | */ | 199 | */ |
270 | 200 | ||
271 | static void inode_go_sync(struct gfs2_glock *gl, int flags) | 201 | static void inode_go_sync(struct gfs2_glock *gl) |
272 | { | 202 | { |
273 | int meta = (flags & DIO_METADATA); | 203 | struct gfs2_inode *ip = gl->gl_object; |
274 | int data = (flags & DIO_DATA); | 204 | |
205 | if (ip && !S_ISREG(ip->i_inode.i_mode)) | ||
206 | ip = NULL; | ||
275 | 207 | ||
276 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 208 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
277 | if (meta && data) { | 209 | gfs2_log_flush(gl->gl_sbd, gl); |
278 | gfs2_page_writeback(gl); | 210 | if (ip) |
279 | gfs2_log_flush(gl->gl_sbd, gl); | 211 | filemap_fdatawrite(ip->i_inode.i_mapping); |
280 | gfs2_meta_sync(gl); | 212 | gfs2_meta_sync(gl); |
281 | gfs2_page_wait(gl); | 213 | if (ip) { |
282 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 214 | struct address_space *mapping = ip->i_inode.i_mapping; |
283 | } else if (meta) { | 215 | int error = filemap_fdatawait(mapping); |
284 | gfs2_log_flush(gl->gl_sbd, gl); | 216 | if (error == -ENOSPC) |
285 | gfs2_meta_sync(gl); | 217 | set_bit(AS_ENOSPC, &mapping->flags); |
286 | } else if (data) { | 218 | else if (error) |
287 | gfs2_page_writeback(gl); | 219 | set_bit(AS_EIO, &mapping->flags); |
288 | gfs2_page_wait(gl); | ||
289 | } | 220 | } |
290 | if (flags & DIO_RELEASE) | 221 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
291 | gfs2_ail_empty_gl(gl); | 222 | gfs2_ail_empty_gl(gl); |
292 | } | 223 | } |
293 | } | 224 | } |
294 | 225 | ||
@@ -301,15 +232,20 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags) | |||
301 | 232 | ||
302 | static void inode_go_inval(struct gfs2_glock *gl, int flags) | 233 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
303 | { | 234 | { |
235 | struct gfs2_inode *ip = gl->gl_object; | ||
304 | int meta = (flags & DIO_METADATA); | 236 | int meta = (flags & DIO_METADATA); |
305 | int data = (flags & DIO_DATA); | ||
306 | 237 | ||
307 | if (meta) { | 238 | if (meta) { |
308 | gfs2_meta_inval(gl); | 239 | gfs2_meta_inval(gl); |
309 | gl->gl_vn++; | 240 | if (ip) |
241 | set_bit(GIF_INVALID, &ip->i_flags); | ||
242 | } | ||
243 | |||
244 | if (ip && S_ISREG(ip->i_inode.i_mode)) { | ||
245 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | ||
246 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); | ||
247 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
310 | } | 248 | } |
311 | if (data) | ||
312 | gfs2_page_inval(gl); | ||
313 | } | 249 | } |
314 | 250 | ||
315 | /** | 251 | /** |
@@ -351,11 +287,10 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
351 | if (!ip) | 287 | if (!ip) |
352 | return 0; | 288 | return 0; |
353 | 289 | ||
354 | if (ip->i_vn != gl->gl_vn) { | 290 | if (test_bit(GIF_INVALID, &ip->i_flags)) { |
355 | error = gfs2_inode_refresh(ip); | 291 | error = gfs2_inode_refresh(ip); |
356 | if (error) | 292 | if (error) |
357 | return error; | 293 | return error; |
358 | gfs2_inode_attr_in(ip); | ||
359 | } | 294 | } |
360 | 295 | ||
361 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && | 296 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && |
@@ -379,11 +314,8 @@ static void inode_go_unlock(struct gfs2_holder *gh) | |||
379 | struct gfs2_glock *gl = gh->gh_gl; | 314 | struct gfs2_glock *gl = gh->gh_gl; |
380 | struct gfs2_inode *ip = gl->gl_object; | 315 | struct gfs2_inode *ip = gl->gl_object; |
381 | 316 | ||
382 | if (ip == NULL) | 317 | if (ip) |
383 | return; | 318 | gfs2_meta_cache_flush(ip); |
384 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) | ||
385 | gfs2_inode_attr_in(ip); | ||
386 | gfs2_meta_cache_flush(ip); | ||
387 | } | 319 | } |
388 | 320 | ||
389 | /** | 321 | /** |
@@ -491,13 +423,13 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
491 | struct gfs2_sbd *sdp = gl->gl_sbd; | 423 | struct gfs2_sbd *sdp = gl->gl_sbd; |
492 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 424 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
493 | struct gfs2_glock *j_gl = ip->i_gl; | 425 | struct gfs2_glock *j_gl = ip->i_gl; |
494 | struct gfs2_log_header head; | 426 | struct gfs2_log_header_host head; |
495 | int error; | 427 | int error; |
496 | 428 | ||
497 | if (gl->gl_state != LM_ST_UNLOCKED && | 429 | if (gl->gl_state != LM_ST_UNLOCKED && |
498 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 430 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
499 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); | 431 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); |
500 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 432 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
501 | 433 | ||
502 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 434 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
503 | if (error) | 435 | if (error) |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 118dc693d111..734421edae85 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define DIO_WAIT 0x00000010 | 15 | #define DIO_WAIT 0x00000010 |
16 | #define DIO_METADATA 0x00000020 | 16 | #define DIO_METADATA 0x00000020 |
17 | #define DIO_DATA 0x00000040 | ||
18 | #define DIO_RELEASE 0x00000080 | ||
19 | #define DIO_ALL 0x00000100 | 17 | #define DIO_ALL 0x00000100 |
20 | 18 | ||
21 | struct gfs2_log_operations; | 19 | struct gfs2_log_operations; |
@@ -41,7 +39,7 @@ struct gfs2_log_operations { | |||
41 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 39 | void (*lo_before_commit) (struct gfs2_sbd *sdp); |
42 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); | 40 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); |
43 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 41 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
44 | struct gfs2_log_header *head, int pass); | 42 | struct gfs2_log_header_host *head, int pass); |
45 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, | 43 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, |
46 | struct gfs2_log_descriptor *ld, __be64 *ptr, | 44 | struct gfs2_log_descriptor *ld, __be64 *ptr, |
47 | int pass); | 45 | int pass); |
@@ -67,8 +65,8 @@ struct gfs2_rgrpd { | |||
67 | struct list_head rd_list_mru; | 65 | struct list_head rd_list_mru; |
68 | struct list_head rd_recent; /* Recently used rgrps */ | 66 | struct list_head rd_recent; /* Recently used rgrps */ |
69 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ | 67 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ |
70 | struct gfs2_rindex rd_ri; | 68 | struct gfs2_rindex_host rd_ri; |
71 | struct gfs2_rgrp rd_rg; | 69 | struct gfs2_rgrp_host rd_rg; |
72 | u64 rd_rg_vn; | 70 | u64 rd_rg_vn; |
73 | struct gfs2_bitmap *rd_bits; | 71 | struct gfs2_bitmap *rd_bits; |
74 | unsigned int rd_bh_count; | 72 | unsigned int rd_bh_count; |
@@ -103,18 +101,17 @@ struct gfs2_bufdata { | |||
103 | }; | 101 | }; |
104 | 102 | ||
105 | struct gfs2_glock_operations { | 103 | struct gfs2_glock_operations { |
106 | void (*go_xmote_th) (struct gfs2_glock * gl, unsigned int state, | 104 | void (*go_xmote_th) (struct gfs2_glock *gl, unsigned int state, int flags); |
107 | int flags); | 105 | void (*go_xmote_bh) (struct gfs2_glock *gl); |
108 | void (*go_xmote_bh) (struct gfs2_glock * gl); | 106 | void (*go_drop_th) (struct gfs2_glock *gl); |
109 | void (*go_drop_th) (struct gfs2_glock * gl); | 107 | void (*go_drop_bh) (struct gfs2_glock *gl); |
110 | void (*go_drop_bh) (struct gfs2_glock * gl); | 108 | void (*go_sync) (struct gfs2_glock *gl); |
111 | void (*go_sync) (struct gfs2_glock * gl, int flags); | 109 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
112 | void (*go_inval) (struct gfs2_glock * gl, int flags); | 110 | int (*go_demote_ok) (struct gfs2_glock *gl); |
113 | int (*go_demote_ok) (struct gfs2_glock * gl); | 111 | int (*go_lock) (struct gfs2_holder *gh); |
114 | int (*go_lock) (struct gfs2_holder * gh); | 112 | void (*go_unlock) (struct gfs2_holder *gh); |
115 | void (*go_unlock) (struct gfs2_holder * gh); | 113 | void (*go_callback) (struct gfs2_glock *gl, unsigned int state); |
116 | void (*go_callback) (struct gfs2_glock * gl, unsigned int state); | 114 | void (*go_greedy) (struct gfs2_glock *gl); |
117 | void (*go_greedy) (struct gfs2_glock * gl); | ||
118 | const int go_type; | 115 | const int go_type; |
119 | }; | 116 | }; |
120 | 117 | ||
@@ -217,6 +214,7 @@ struct gfs2_alloc { | |||
217 | }; | 214 | }; |
218 | 215 | ||
219 | enum { | 216 | enum { |
217 | GIF_INVALID = 0, | ||
220 | GIF_QD_LOCKED = 1, | 218 | GIF_QD_LOCKED = 1, |
221 | GIF_PAGED = 2, | 219 | GIF_PAGED = 2, |
222 | GIF_SW_PAGED = 3, | 220 | GIF_SW_PAGED = 3, |
@@ -224,12 +222,11 @@ enum { | |||
224 | 222 | ||
225 | struct gfs2_inode { | 223 | struct gfs2_inode { |
226 | struct inode i_inode; | 224 | struct inode i_inode; |
227 | struct gfs2_inum i_num; | 225 | struct gfs2_inum_host i_num; |
228 | 226 | ||
229 | unsigned long i_flags; /* GIF_... */ | 227 | unsigned long i_flags; /* GIF_... */ |
230 | 228 | ||
231 | u64 i_vn; | 229 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ |
232 | struct gfs2_dinode i_di; /* To be replaced by ref to block */ | ||
233 | 230 | ||
234 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 231 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
235 | struct gfs2_holder i_iopen_gh; | 232 | struct gfs2_holder i_iopen_gh; |
@@ -450,7 +447,7 @@ struct gfs2_sbd { | |||
450 | struct super_block *sd_vfs_meta; | 447 | struct super_block *sd_vfs_meta; |
451 | struct kobject sd_kobj; | 448 | struct kobject sd_kobj; |
452 | unsigned long sd_flags; /* SDF_... */ | 449 | unsigned long sd_flags; /* SDF_... */ |
453 | struct gfs2_sb sd_sb; | 450 | struct gfs2_sb_host sd_sb; |
454 | 451 | ||
455 | /* Constants computed on mount */ | 452 | /* Constants computed on mount */ |
456 | 453 | ||
@@ -503,8 +500,8 @@ struct gfs2_sbd { | |||
503 | 500 | ||
504 | spinlock_t sd_statfs_spin; | 501 | spinlock_t sd_statfs_spin; |
505 | struct mutex sd_statfs_mutex; | 502 | struct mutex sd_statfs_mutex; |
506 | struct gfs2_statfs_change sd_statfs_master; | 503 | struct gfs2_statfs_change_host sd_statfs_master; |
507 | struct gfs2_statfs_change sd_statfs_local; | 504 | struct gfs2_statfs_change_host sd_statfs_local; |
508 | unsigned long sd_statfs_sync_time; | 505 | unsigned long sd_statfs_sync_time; |
509 | 506 | ||
510 | /* Resource group stuff */ | 507 | /* Resource group stuff */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index d470e5286ecd..d122074c45e1 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -38,83 +38,12 @@ | |||
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | 40 | ||
41 | /** | ||
42 | * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode | ||
43 | * @ip: The GFS2 inode (with embedded disk inode data) | ||
44 | * @inode: The Linux VFS inode | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | void gfs2_inode_attr_in(struct gfs2_inode *ip) | ||
49 | { | ||
50 | struct inode *inode = &ip->i_inode; | ||
51 | struct gfs2_dinode *di = &ip->i_di; | ||
52 | |||
53 | inode->i_ino = ip->i_num.no_addr; | ||
54 | |||
55 | switch (di->di_mode & S_IFMT) { | ||
56 | case S_IFBLK: | ||
57 | case S_IFCHR: | ||
58 | inode->i_rdev = MKDEV(di->di_major, di->di_minor); | ||
59 | break; | ||
60 | default: | ||
61 | inode->i_rdev = 0; | ||
62 | break; | ||
63 | }; | ||
64 | |||
65 | inode->i_mode = di->di_mode; | ||
66 | inode->i_nlink = di->di_nlink; | ||
67 | inode->i_uid = di->di_uid; | ||
68 | inode->i_gid = di->di_gid; | ||
69 | i_size_write(inode, di->di_size); | ||
70 | inode->i_atime.tv_sec = di->di_atime; | ||
71 | inode->i_mtime.tv_sec = di->di_mtime; | ||
72 | inode->i_ctime.tv_sec = di->di_ctime; | ||
73 | inode->i_atime.tv_nsec = 0; | ||
74 | inode->i_mtime.tv_nsec = 0; | ||
75 | inode->i_ctime.tv_nsec = 0; | ||
76 | inode->i_blocks = di->di_blocks << | ||
77 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
78 | |||
79 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
80 | inode->i_flags |= S_IMMUTABLE; | ||
81 | else | ||
82 | inode->i_flags &= ~S_IMMUTABLE; | ||
83 | |||
84 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
85 | inode->i_flags |= S_APPEND; | ||
86 | else | ||
87 | inode->i_flags &= ~S_APPEND; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode | ||
92 | * @ip: The GFS2 inode | ||
93 | * | ||
94 | * Only copy out the attributes that we want the VFS layer | ||
95 | * to be able to modify. | ||
96 | */ | ||
97 | |||
98 | void gfs2_inode_attr_out(struct gfs2_inode *ip) | ||
99 | { | ||
100 | struct inode *inode = &ip->i_inode; | ||
101 | struct gfs2_dinode *di = &ip->i_di; | ||
102 | gfs2_assert_withdraw(GFS2_SB(inode), | ||
103 | (di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT)); | ||
104 | di->di_mode = inode->i_mode; | ||
105 | di->di_uid = inode->i_uid; | ||
106 | di->di_gid = inode->i_gid; | ||
107 | di->di_atime = inode->i_atime.tv_sec; | ||
108 | di->di_mtime = inode->i_mtime.tv_sec; | ||
109 | di->di_ctime = inode->i_ctime.tv_sec; | ||
110 | } | ||
111 | |||
112 | static int iget_test(struct inode *inode, void *opaque) | 41 | static int iget_test(struct inode *inode, void *opaque) |
113 | { | 42 | { |
114 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
115 | struct gfs2_inum *inum = opaque; | 44 | struct gfs2_inum_host *inum = opaque; |
116 | 45 | ||
117 | if (ip && ip->i_num.no_addr == inum->no_addr) | 46 | if (ip->i_num.no_addr == inum->no_addr) |
118 | return 1; | 47 | return 1; |
119 | 48 | ||
120 | return 0; | 49 | return 0; |
@@ -123,19 +52,20 @@ static int iget_test(struct inode *inode, void *opaque) | |||
123 | static int iget_set(struct inode *inode, void *opaque) | 52 | static int iget_set(struct inode *inode, void *opaque) |
124 | { | 53 | { |
125 | struct gfs2_inode *ip = GFS2_I(inode); | 54 | struct gfs2_inode *ip = GFS2_I(inode); |
126 | struct gfs2_inum *inum = opaque; | 55 | struct gfs2_inum_host *inum = opaque; |
127 | 56 | ||
128 | ip->i_num = *inum; | 57 | ip->i_num = *inum; |
58 | inode->i_ino = inum->no_addr; | ||
129 | return 0; | 59 | return 0; |
130 | } | 60 | } |
131 | 61 | ||
132 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum) | 62 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) |
133 | { | 63 | { |
134 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, | 64 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, |
135 | iget_test, inum); | 65 | iget_test, inum); |
136 | } | 66 | } |
137 | 67 | ||
138 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | 68 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) |
139 | { | 69 | { |
140 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, | 70 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, |
141 | iget_test, iget_set, inum); | 71 | iget_test, iget_set, inum); |
@@ -150,7 +80,7 @@ static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | |||
150 | * Returns: A VFS inode, or an error | 80 | * Returns: A VFS inode, or an error |
151 | */ | 81 | */ |
152 | 82 | ||
153 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type) | 83 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) |
154 | { | 84 | { |
155 | struct inode *inode = gfs2_iget(sb, inum); | 85 | struct inode *inode = gfs2_iget(sb, inum); |
156 | struct gfs2_inode *ip = GFS2_I(inode); | 86 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -188,7 +118,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, | |||
188 | if (unlikely(error)) | 118 | if (unlikely(error)) |
189 | goto fail_put; | 119 | goto fail_put; |
190 | 120 | ||
191 | ip->i_vn = ip->i_gl->gl_vn - 1; | 121 | set_bit(GIF_INVALID, &ip->i_flags); |
192 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 122 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
193 | if (unlikely(error)) | 123 | if (unlikely(error)) |
194 | goto fail_iopen; | 124 | goto fail_iopen; |
@@ -208,6 +138,63 @@ fail: | |||
208 | return ERR_PTR(error); | 138 | return ERR_PTR(error); |
209 | } | 139 | } |
210 | 140 | ||
141 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
142 | { | ||
143 | struct gfs2_dinode_host *di = &ip->i_di; | ||
144 | const struct gfs2_dinode *str = buf; | ||
145 | |||
146 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | ||
147 | if (gfs2_consist_inode(ip)) | ||
148 | gfs2_dinode_print(ip); | ||
149 | return -EIO; | ||
150 | } | ||
151 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | ||
152 | return -ESTALE; | ||
153 | |||
154 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
155 | ip->i_inode.i_rdev = 0; | ||
156 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
157 | case S_IFBLK: | ||
158 | case S_IFCHR: | ||
159 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
160 | be32_to_cpu(str->di_minor)); | ||
161 | break; | ||
162 | }; | ||
163 | |||
164 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
165 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
166 | /* | ||
167 | * We will need to review setting the nlink count here in the | ||
168 | * light of the forthcoming ro bind mount work. This is a reminder | ||
169 | * to do that. | ||
170 | */ | ||
171 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | ||
172 | di->di_size = be64_to_cpu(str->di_size); | ||
173 | i_size_write(&ip->i_inode, di->di_size); | ||
174 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
175 | gfs2_set_inode_blocks(&ip->i_inode); | ||
176 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | ||
177 | ip->i_inode.i_atime.tv_nsec = 0; | ||
178 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
179 | ip->i_inode.i_mtime.tv_nsec = 0; | ||
180 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
181 | ip->i_inode.i_ctime.tv_nsec = 0; | ||
182 | |||
183 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
184 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
185 | di->di_generation = be64_to_cpu(str->di_generation); | ||
186 | |||
187 | di->di_flags = be32_to_cpu(str->di_flags); | ||
188 | gfs2_set_inode_flags(&ip->i_inode); | ||
189 | di->di_height = be16_to_cpu(str->di_height); | ||
190 | |||
191 | di->di_depth = be16_to_cpu(str->di_depth); | ||
192 | di->di_entries = be32_to_cpu(str->di_entries); | ||
193 | |||
194 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
211 | /** | 198 | /** |
212 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 199 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
213 | * @ip: The GFS2 inode | 200 | * @ip: The GFS2 inode |
@@ -229,21 +216,11 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) | |||
229 | return -EIO; | 216 | return -EIO; |
230 | } | 217 | } |
231 | 218 | ||
232 | gfs2_dinode_in(&ip->i_di, dibh->b_data); | 219 | error = gfs2_dinode_in(ip, dibh->b_data); |
233 | |||
234 | brelse(dibh); | 220 | brelse(dibh); |
221 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
235 | 222 | ||
236 | if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { | 223 | return error; |
237 | if (gfs2_consist_inode(ip)) | ||
238 | gfs2_dinode_print(&ip->i_di); | ||
239 | return -EIO; | ||
240 | } | ||
241 | if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) | ||
242 | return -ESTALE; | ||
243 | |||
244 | ip->i_vn = ip->i_gl->gl_vn; | ||
245 | |||
246 | return 0; | ||
247 | } | 224 | } |
248 | 225 | ||
249 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 226 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
@@ -255,7 +232,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
255 | 232 | ||
256 | if (ip->i_di.di_blocks != 1) { | 233 | if (ip->i_di.di_blocks != 1) { |
257 | if (gfs2_consist_inode(ip)) | 234 | if (gfs2_consist_inode(ip)) |
258 | gfs2_dinode_print(&ip->i_di); | 235 | gfs2_dinode_print(ip); |
259 | return -EIO; | 236 | return -EIO; |
260 | } | 237 | } |
261 | 238 | ||
@@ -318,14 +295,14 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
318 | u32 nlink; | 295 | u32 nlink; |
319 | int error; | 296 | int error; |
320 | 297 | ||
321 | BUG_ON(ip->i_di.di_nlink != ip->i_inode.i_nlink); | 298 | BUG_ON(diff != 1 && diff != -1); |
322 | nlink = ip->i_di.di_nlink + diff; | 299 | nlink = ip->i_inode.i_nlink + diff; |
323 | 300 | ||
324 | /* If we are reducing the nlink count, but the new value ends up being | 301 | /* If we are reducing the nlink count, but the new value ends up being |
325 | bigger than the old one, we must have underflowed. */ | 302 | bigger than the old one, we must have underflowed. */ |
326 | if (diff < 0 && nlink > ip->i_di.di_nlink) { | 303 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
327 | if (gfs2_consist_inode(ip)) | 304 | if (gfs2_consist_inode(ip)) |
328 | gfs2_dinode_print(&ip->i_di); | 305 | gfs2_dinode_print(ip); |
329 | return -EIO; | 306 | return -EIO; |
330 | } | 307 | } |
331 | 308 | ||
@@ -333,16 +310,19 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
333 | if (error) | 310 | if (error) |
334 | return error; | 311 | return error; |
335 | 312 | ||
336 | ip->i_di.di_nlink = nlink; | 313 | if (diff > 0) |
337 | ip->i_di.di_ctime = get_seconds(); | 314 | inc_nlink(&ip->i_inode); |
338 | ip->i_inode.i_nlink = nlink; | 315 | else |
316 | drop_nlink(&ip->i_inode); | ||
317 | |||
318 | ip->i_inode.i_ctime.tv_sec = get_seconds(); | ||
339 | 319 | ||
340 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 320 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
341 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 321 | gfs2_dinode_out(ip, dibh->b_data); |
342 | brelse(dibh); | 322 | brelse(dibh); |
343 | mark_inode_dirty(&ip->i_inode); | 323 | mark_inode_dirty(&ip->i_inode); |
344 | 324 | ||
345 | if (ip->i_di.di_nlink == 0) { | 325 | if (ip->i_inode.i_nlink == 0) { |
346 | struct gfs2_rgrpd *rgd; | 326 | struct gfs2_rgrpd *rgd; |
347 | struct gfs2_holder ri_gh, rg_gh; | 327 | struct gfs2_holder ri_gh, rg_gh; |
348 | 328 | ||
@@ -357,7 +337,6 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
357 | if (error) | 337 | if (error) |
358 | goto out_norgrp; | 338 | goto out_norgrp; |
359 | 339 | ||
360 | clear_nlink(&ip->i_inode); | ||
361 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 340 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
362 | gfs2_glock_dq_uninit(&rg_gh); | 341 | gfs2_glock_dq_uninit(&rg_gh); |
363 | out_norgrp: | 342 | out_norgrp: |
@@ -394,7 +373,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
394 | struct super_block *sb = dir->i_sb; | 373 | struct super_block *sb = dir->i_sb; |
395 | struct gfs2_inode *dip = GFS2_I(dir); | 374 | struct gfs2_inode *dip = GFS2_I(dir); |
396 | struct gfs2_holder d_gh; | 375 | struct gfs2_holder d_gh; |
397 | struct gfs2_inum inum; | 376 | struct gfs2_inum_host inum; |
398 | unsigned int type; | 377 | unsigned int type; |
399 | int error = 0; | 378 | int error = 0; |
400 | struct inode *inode = NULL; | 379 | struct inode *inode = NULL; |
@@ -436,7 +415,7 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
436 | { | 415 | { |
437 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 416 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
438 | struct buffer_head *bh; | 417 | struct buffer_head *bh; |
439 | struct gfs2_inum_range ir; | 418 | struct gfs2_inum_range_host ir; |
440 | int error; | 419 | int error; |
441 | 420 | ||
442 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 421 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
@@ -479,7 +458,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
479 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 458 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
480 | struct gfs2_holder gh; | 459 | struct gfs2_holder gh; |
481 | struct buffer_head *bh; | 460 | struct buffer_head *bh; |
482 | struct gfs2_inum_range ir; | 461 | struct gfs2_inum_range_host ir; |
483 | int error; | 462 | int error; |
484 | 463 | ||
485 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 464 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
@@ -500,21 +479,22 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
500 | if (!ir.ir_length) { | 479 | if (!ir.ir_length) { |
501 | struct buffer_head *m_bh; | 480 | struct buffer_head *m_bh; |
502 | u64 x, y; | 481 | u64 x, y; |
482 | __be64 z; | ||
503 | 483 | ||
504 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 484 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
505 | if (error) | 485 | if (error) |
506 | goto out_brelse; | 486 | goto out_brelse; |
507 | 487 | ||
508 | x = *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 488 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
509 | x = y = be64_to_cpu(x); | 489 | x = y = be64_to_cpu(z); |
510 | ir.ir_start = x; | 490 | ir.ir_start = x; |
511 | ir.ir_length = GFS2_INUM_QUANTUM; | 491 | ir.ir_length = GFS2_INUM_QUANTUM; |
512 | x += GFS2_INUM_QUANTUM; | 492 | x += GFS2_INUM_QUANTUM; |
513 | if (x < y) | 493 | if (x < y) |
514 | gfs2_consist_inode(m_ip); | 494 | gfs2_consist_inode(m_ip); |
515 | x = cpu_to_be64(x); | 495 | z = cpu_to_be64(x); |
516 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 496 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
517 | *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x; | 497 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
518 | 498 | ||
519 | brelse(m_bh); | 499 | brelse(m_bh); |
520 | } | 500 | } |
@@ -567,7 +547,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
567 | return error; | 547 | return error; |
568 | 548 | ||
569 | /* Don't create entries in an unlinked directory */ | 549 | /* Don't create entries in an unlinked directory */ |
570 | if (!dip->i_di.di_nlink) | 550 | if (!dip->i_inode.i_nlink) |
571 | return -EPERM; | 551 | return -EPERM; |
572 | 552 | ||
573 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 553 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); |
@@ -583,7 +563,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
583 | 563 | ||
584 | if (dip->i_di.di_entries == (u32)-1) | 564 | if (dip->i_di.di_entries == (u32)-1) |
585 | return -EFBIG; | 565 | return -EFBIG; |
586 | if (S_ISDIR(mode) && dip->i_di.di_nlink == (u32)-1) | 566 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
587 | return -EMLINK; | 567 | return -EMLINK; |
588 | 568 | ||
589 | return 0; | 569 | return 0; |
@@ -593,24 +573,24 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
593 | unsigned int *uid, unsigned int *gid) | 573 | unsigned int *uid, unsigned int *gid) |
594 | { | 574 | { |
595 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 575 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
596 | (dip->i_di.di_mode & S_ISUID) && dip->i_di.di_uid) { | 576 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
597 | if (S_ISDIR(*mode)) | 577 | if (S_ISDIR(*mode)) |
598 | *mode |= S_ISUID; | 578 | *mode |= S_ISUID; |
599 | else if (dip->i_di.di_uid != current->fsuid) | 579 | else if (dip->i_inode.i_uid != current->fsuid) |
600 | *mode &= ~07111; | 580 | *mode &= ~07111; |
601 | *uid = dip->i_di.di_uid; | 581 | *uid = dip->i_inode.i_uid; |
602 | } else | 582 | } else |
603 | *uid = current->fsuid; | 583 | *uid = current->fsuid; |
604 | 584 | ||
605 | if (dip->i_di.di_mode & S_ISGID) { | 585 | if (dip->i_inode.i_mode & S_ISGID) { |
606 | if (S_ISDIR(*mode)) | 586 | if (S_ISDIR(*mode)) |
607 | *mode |= S_ISGID; | 587 | *mode |= S_ISGID; |
608 | *gid = dip->i_di.di_gid; | 588 | *gid = dip->i_inode.i_gid; |
609 | } else | 589 | } else |
610 | *gid = current->fsgid; | 590 | *gid = current->fsgid; |
611 | } | 591 | } |
612 | 592 | ||
613 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum, | 593 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, |
614 | u64 *generation) | 594 | u64 *generation) |
615 | { | 595 | { |
616 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 596 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
@@ -650,9 +630,9 @@ out: | |||
650 | */ | 630 | */ |
651 | 631 | ||
652 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 632 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
653 | const struct gfs2_inum *inum, unsigned int mode, | 633 | const struct gfs2_inum_host *inum, unsigned int mode, |
654 | unsigned int uid, unsigned int gid, | 634 | unsigned int uid, unsigned int gid, |
655 | const u64 *generation) | 635 | const u64 *generation, dev_t dev) |
656 | { | 636 | { |
657 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 637 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
658 | struct gfs2_dinode *di; | 638 | struct gfs2_dinode *di; |
@@ -669,14 +649,15 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
669 | di->di_mode = cpu_to_be32(mode); | 649 | di->di_mode = cpu_to_be32(mode); |
670 | di->di_uid = cpu_to_be32(uid); | 650 | di->di_uid = cpu_to_be32(uid); |
671 | di->di_gid = cpu_to_be32(gid); | 651 | di->di_gid = cpu_to_be32(gid); |
672 | di->di_nlink = cpu_to_be32(0); | 652 | di->di_nlink = 0; |
673 | di->di_size = cpu_to_be64(0); | 653 | di->di_size = 0; |
674 | di->di_blocks = cpu_to_be64(1); | 654 | di->di_blocks = cpu_to_be64(1); |
675 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); | 655 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); |
676 | di->di_major = di->di_minor = cpu_to_be32(0); | 656 | di->di_major = cpu_to_be32(MAJOR(dev)); |
657 | di->di_minor = cpu_to_be32(MINOR(dev)); | ||
677 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 658 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
678 | di->di_generation = cpu_to_be64(*generation); | 659 | di->di_generation = cpu_to_be64(*generation); |
679 | di->di_flags = cpu_to_be32(0); | 660 | di->di_flags = 0; |
680 | 661 | ||
681 | if (S_ISREG(mode)) { | 662 | if (S_ISREG(mode)) { |
682 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 663 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || |
@@ -693,22 +674,22 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
693 | } | 674 | } |
694 | 675 | ||
695 | di->__pad1 = 0; | 676 | di->__pad1 = 0; |
696 | di->di_payload_format = cpu_to_be32(0); | 677 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
697 | di->di_height = cpu_to_be32(0); | 678 | di->di_height = 0; |
698 | di->__pad2 = 0; | 679 | di->__pad2 = 0; |
699 | di->__pad3 = 0; | 680 | di->__pad3 = 0; |
700 | di->di_depth = cpu_to_be16(0); | 681 | di->di_depth = 0; |
701 | di->di_entries = cpu_to_be32(0); | 682 | di->di_entries = 0; |
702 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 683 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
703 | di->di_eattr = cpu_to_be64(0); | 684 | di->di_eattr = 0; |
704 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 685 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
705 | 686 | ||
706 | brelse(dibh); | 687 | brelse(dibh); |
707 | } | 688 | } |
708 | 689 | ||
709 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 690 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
710 | unsigned int mode, const struct gfs2_inum *inum, | 691 | unsigned int mode, const struct gfs2_inum_host *inum, |
711 | const u64 *generation) | 692 | const u64 *generation, dev_t dev) |
712 | { | 693 | { |
713 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 694 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
714 | unsigned int uid, gid; | 695 | unsigned int uid, gid; |
@@ -729,7 +710,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
729 | if (error) | 710 | if (error) |
730 | goto out_quota; | 711 | goto out_quota; |
731 | 712 | ||
732 | init_dinode(dip, gl, inum, mode, uid, gid, generation); | 713 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev); |
733 | gfs2_quota_change(dip, +1, uid, gid); | 714 | gfs2_quota_change(dip, +1, uid, gid); |
734 | gfs2_trans_end(sdp); | 715 | gfs2_trans_end(sdp); |
735 | 716 | ||
@@ -759,8 +740,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
759 | if (alloc_required < 0) | 740 | if (alloc_required < 0) |
760 | goto fail; | 741 | goto fail; |
761 | if (alloc_required) { | 742 | if (alloc_required) { |
762 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 743 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
763 | dip->i_di.di_gid); | ||
764 | if (error) | 744 | if (error) |
765 | goto fail_quota_locks; | 745 | goto fail_quota_locks; |
766 | 746 | ||
@@ -782,16 +762,16 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
782 | goto fail_quota_locks; | 762 | goto fail_quota_locks; |
783 | } | 763 | } |
784 | 764 | ||
785 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); | 765 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); |
786 | if (error) | 766 | if (error) |
787 | goto fail_end_trans; | 767 | goto fail_end_trans; |
788 | 768 | ||
789 | error = gfs2_meta_inode_buffer(ip, &dibh); | 769 | error = gfs2_meta_inode_buffer(ip, &dibh); |
790 | if (error) | 770 | if (error) |
791 | goto fail_end_trans; | 771 | goto fail_end_trans; |
792 | ip->i_di.di_nlink = 1; | 772 | ip->i_inode.i_nlink = 1; |
793 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 773 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
794 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 774 | gfs2_dinode_out(ip, dibh->b_data); |
795 | brelse(dibh); | 775 | brelse(dibh); |
796 | return 0; | 776 | return 0; |
797 | 777 | ||
@@ -860,13 +840,13 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
860 | */ | 840 | */ |
861 | 841 | ||
862 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 842 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
863 | unsigned int mode) | 843 | unsigned int mode, dev_t dev) |
864 | { | 844 | { |
865 | struct inode *inode; | 845 | struct inode *inode; |
866 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 846 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
867 | struct inode *dir = &dip->i_inode; | 847 | struct inode *dir = &dip->i_inode; |
868 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 848 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
869 | struct gfs2_inum inum; | 849 | struct gfs2_inum_host inum; |
870 | int error; | 850 | int error; |
871 | u64 generation; | 851 | u64 generation; |
872 | 852 | ||
@@ -890,35 +870,12 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
890 | if (error) | 870 | if (error) |
891 | goto fail_gunlock; | 871 | goto fail_gunlock; |
892 | 872 | ||
893 | if (inum.no_addr < dip->i_num.no_addr) { | 873 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
894 | gfs2_glock_dq(ghs); | 874 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
895 | 875 | if (error) | |
896 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | 876 | goto fail_gunlock; |
897 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
898 | GL_SKIP, ghs + 1); | ||
899 | if (error) { | ||
900 | return ERR_PTR(error); | ||
901 | } | ||
902 | |||
903 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | ||
904 | error = gfs2_glock_nq(ghs); | ||
905 | if (error) { | ||
906 | gfs2_glock_dq_uninit(ghs + 1); | ||
907 | return ERR_PTR(error); | ||
908 | } | ||
909 | |||
910 | error = create_ok(dip, name, mode); | ||
911 | if (error) | ||
912 | goto fail_gunlock2; | ||
913 | } else { | ||
914 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | ||
915 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
916 | GL_SKIP, ghs + 1); | ||
917 | if (error) | ||
918 | goto fail_gunlock; | ||
919 | } | ||
920 | 877 | ||
921 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation); | 878 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev); |
922 | if (error) | 879 | if (error) |
923 | goto fail_gunlock2; | 880 | goto fail_gunlock2; |
924 | 881 | ||
@@ -975,7 +932,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
975 | 932 | ||
976 | if (ip->i_di.di_entries != 2) { | 933 | if (ip->i_di.di_entries != 2) { |
977 | if (gfs2_consist_inode(ip)) | 934 | if (gfs2_consist_inode(ip)) |
978 | gfs2_dinode_print(&ip->i_di); | 935 | gfs2_dinode_print(ip); |
979 | return -EIO; | 936 | return -EIO; |
980 | } | 937 | } |
981 | 938 | ||
@@ -997,7 +954,12 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
997 | if (error) | 954 | if (error) |
998 | return error; | 955 | return error; |
999 | 956 | ||
1000 | error = gfs2_change_nlink(ip, -2); | 957 | /* It looks odd, but it really should be done twice */ |
958 | error = gfs2_change_nlink(ip, -1); | ||
959 | if (error) | ||
960 | return error; | ||
961 | |||
962 | error = gfs2_change_nlink(ip, -1); | ||
1001 | if (error) | 963 | if (error) |
1002 | return error; | 964 | return error; |
1003 | 965 | ||
@@ -1018,16 +980,16 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
1018 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 980 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
1019 | struct gfs2_inode *ip) | 981 | struct gfs2_inode *ip) |
1020 | { | 982 | { |
1021 | struct gfs2_inum inum; | 983 | struct gfs2_inum_host inum; |
1022 | unsigned int type; | 984 | unsigned int type; |
1023 | int error; | 985 | int error; |
1024 | 986 | ||
1025 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 987 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
1026 | return -EPERM; | 988 | return -EPERM; |
1027 | 989 | ||
1028 | if ((dip->i_di.di_mode & S_ISVTX) && | 990 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1029 | dip->i_di.di_uid != current->fsuid && | 991 | dip->i_inode.i_uid != current->fsuid && |
1030 | ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) | 992 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) |
1031 | return -EPERM; | 993 | return -EPERM; |
1032 | 994 | ||
1033 | if (IS_APPEND(&dip->i_inode)) | 995 | if (IS_APPEND(&dip->i_inode)) |
@@ -1044,7 +1006,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
1044 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | 1006 | if (!gfs2_inum_equal(&inum, &ip->i_num)) |
1045 | return -ENOENT; | 1007 | return -ENOENT; |
1046 | 1008 | ||
1047 | if (IF2DT(ip->i_di.di_mode) != type) { | 1009 | if (IF2DT(ip->i_inode.i_mode) != type) { |
1048 | gfs2_consist_inode(dip); | 1010 | gfs2_consist_inode(dip); |
1049 | return -EIO; | 1011 | return -EIO; |
1050 | } | 1012 | } |
@@ -1194,7 +1156,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1194 | return 0; | 1156 | return 0; |
1195 | 1157 | ||
1196 | curtime = get_seconds(); | 1158 | curtime = get_seconds(); |
1197 | if (curtime - ip->i_di.di_atime >= quantum) { | 1159 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1198 | gfs2_glock_dq(gh); | 1160 | gfs2_glock_dq(gh); |
1199 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1161 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1200 | gh); | 1162 | gh); |
@@ -1206,7 +1168,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1206 | trying to get exclusive lock. */ | 1168 | trying to get exclusive lock. */ |
1207 | 1169 | ||
1208 | curtime = get_seconds(); | 1170 | curtime = get_seconds(); |
1209 | if (curtime - ip->i_di.di_atime >= quantum) { | 1171 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1210 | struct buffer_head *dibh; | 1172 | struct buffer_head *dibh; |
1211 | struct gfs2_dinode *di; | 1173 | struct gfs2_dinode *di; |
1212 | 1174 | ||
@@ -1220,11 +1182,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1220 | if (error) | 1182 | if (error) |
1221 | goto fail_end_trans; | 1183 | goto fail_end_trans; |
1222 | 1184 | ||
1223 | ip->i_di.di_atime = curtime; | 1185 | ip->i_inode.i_atime.tv_sec = curtime; |
1224 | 1186 | ||
1225 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1187 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1226 | di = (struct gfs2_dinode *)dibh->b_data; | 1188 | di = (struct gfs2_dinode *)dibh->b_data; |
1227 | di->di_atime = cpu_to_be64(ip->i_di.di_atime); | 1189 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1228 | brelse(dibh); | 1190 | brelse(dibh); |
1229 | 1191 | ||
1230 | gfs2_trans_end(sdp); | 1192 | gfs2_trans_end(sdp); |
@@ -1249,92 +1211,6 @@ fail: | |||
1249 | return error; | 1211 | return error; |
1250 | } | 1212 | } |
1251 | 1213 | ||
1252 | /** | ||
1253 | * glock_compare_atime - Compare two struct gfs2_glock structures for sort | ||
1254 | * @arg_a: the first structure | ||
1255 | * @arg_b: the second structure | ||
1256 | * | ||
1257 | * Returns: 1 if A > B | ||
1258 | * -1 if A < B | ||
1259 | * 0 if A == B | ||
1260 | */ | ||
1261 | |||
1262 | static int glock_compare_atime(const void *arg_a, const void *arg_b) | ||
1263 | { | ||
1264 | const struct gfs2_holder *gh_a = *(const struct gfs2_holder **)arg_a; | ||
1265 | const struct gfs2_holder *gh_b = *(const struct gfs2_holder **)arg_b; | ||
1266 | const struct lm_lockname *a = &gh_a->gh_gl->gl_name; | ||
1267 | const struct lm_lockname *b = &gh_b->gh_gl->gl_name; | ||
1268 | |||
1269 | if (a->ln_number > b->ln_number) | ||
1270 | return 1; | ||
1271 | if (a->ln_number < b->ln_number) | ||
1272 | return -1; | ||
1273 | if (gh_a->gh_state == LM_ST_SHARED && gh_b->gh_state == LM_ST_EXCLUSIVE) | ||
1274 | return 1; | ||
1275 | if (gh_a->gh_state == LM_ST_SHARED && (gh_b->gh_flags & GL_ATIME)) | ||
1276 | return 1; | ||
1277 | |||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an | ||
1283 | * atime update | ||
1284 | * @num_gh: the number of structures | ||
1285 | * @ghs: an array of struct gfs2_holder structures | ||
1286 | * | ||
1287 | * Returns: 0 on success (all glocks acquired), | ||
1288 | * errno on failure (no glocks acquired) | ||
1289 | */ | ||
1290 | |||
1291 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs) | ||
1292 | { | ||
1293 | struct gfs2_holder **p; | ||
1294 | unsigned int x; | ||
1295 | int error = 0; | ||
1296 | |||
1297 | if (!num_gh) | ||
1298 | return 0; | ||
1299 | |||
1300 | if (num_gh == 1) { | ||
1301 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1302 | if (ghs->gh_flags & GL_ATIME) | ||
1303 | error = gfs2_glock_nq_atime(ghs); | ||
1304 | else | ||
1305 | error = gfs2_glock_nq(ghs); | ||
1306 | return error; | ||
1307 | } | ||
1308 | |||
1309 | p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1310 | if (!p) | ||
1311 | return -ENOMEM; | ||
1312 | |||
1313 | for (x = 0; x < num_gh; x++) | ||
1314 | p[x] = &ghs[x]; | ||
1315 | |||
1316 | sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL); | ||
1317 | |||
1318 | for (x = 0; x < num_gh; x++) { | ||
1319 | p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1320 | |||
1321 | if (p[x]->gh_flags & GL_ATIME) | ||
1322 | error = gfs2_glock_nq_atime(p[x]); | ||
1323 | else | ||
1324 | error = gfs2_glock_nq(p[x]); | ||
1325 | |||
1326 | if (error) { | ||
1327 | while (x--) | ||
1328 | gfs2_glock_dq(p[x]); | ||
1329 | break; | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | kfree(p); | ||
1334 | return error; | ||
1335 | } | ||
1336 | |||
1337 | |||
1338 | static int | 1214 | static int |
1339 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1215 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1340 | { | 1216 | { |
@@ -1345,10 +1221,8 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1345 | if (!error) { | 1221 | if (!error) { |
1346 | error = inode_setattr(&ip->i_inode, attr); | 1222 | error = inode_setattr(&ip->i_inode, attr); |
1347 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1223 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1348 | gfs2_inode_attr_out(ip); | ||
1349 | |||
1350 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1224 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1351 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1225 | gfs2_dinode_out(ip, dibh->b_data); |
1352 | brelse(dibh); | 1226 | brelse(dibh); |
1353 | } | 1227 | } |
1354 | return error; | 1228 | return error; |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index f5d861760579..b57f448b15bc 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -22,13 +22,19 @@ static inline int gfs2_is_jdata(struct gfs2_inode *ip) | |||
22 | 22 | ||
23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) | 23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) |
24 | { | 24 | { |
25 | return S_ISDIR(ip->i_di.di_mode); | 25 | return S_ISDIR(ip->i_inode.i_mode); |
26 | } | ||
27 | |||
28 | static inline void gfs2_set_inode_blocks(struct inode *inode) | ||
29 | { | ||
30 | struct gfs2_inode *ip = GFS2_I(inode); | ||
31 | inode->i_blocks = ip->i_di.di_blocks << | ||
32 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
26 | } | 33 | } |
27 | 34 | ||
28 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 35 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
29 | void gfs2_inode_attr_out(struct gfs2_inode *ip); | 36 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); |
30 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type); | 37 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); |
31 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum); | ||
32 | 38 | ||
33 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 39 | int gfs2_inode_refresh(struct gfs2_inode *ip); |
34 | 40 | ||
@@ -37,19 +43,15 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | |||
37 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 43 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
38 | int is_root, struct nameidata *nd); | 44 | int is_root, struct nameidata *nd); |
39 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 45 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
40 | unsigned int mode); | 46 | unsigned int mode, dev_t dev); |
41 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 47 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
42 | struct gfs2_inode *ip); | 48 | struct gfs2_inode *ip); |
43 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 49 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
44 | struct gfs2_inode *ip); | 50 | struct gfs2_inode *ip); |
45 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); | 51 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); |
46 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 52 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); |
47 | |||
48 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); | 53 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); |
49 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs); | ||
50 | |||
51 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 54 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
52 | |||
53 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 55 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
54 | 56 | ||
55 | #endif /* __INODE_DOT_H__ */ | 57 | #endif /* __INODE_DOT_H__ */ |
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index 7365aec9511b..3799f19b282f 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/miscdevice.h> | 9 | #include <linux/miscdevice.h> |
10 | #include <linux/lock_dlm_plock.h> | 10 | #include <linux/lock_dlm_plock.h> |
11 | #include <linux/poll.h> | ||
11 | 12 | ||
12 | #include "lock_dlm.h" | 13 | #include "lock_dlm.h" |
13 | 14 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 0cace3da9dbb..291415ddfe51 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
17 | #include <linux/lm_interface.h> | 17 | #include <linux/lm_interface.h> |
18 | #include <linux/delay.h> | ||
18 | 19 | ||
19 | #include "gfs2.h" | 20 | #include "gfs2.h" |
20 | #include "incore.h" | 21 | #include "incore.h" |
@@ -142,7 +143,7 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
142 | return list_empty(&ai->ai_ail1_list); | 143 | return list_empty(&ai->ai_ail1_list); |
143 | } | 144 | } |
144 | 145 | ||
145 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) | 146 | static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) |
146 | { | 147 | { |
147 | struct list_head *head = &sdp->sd_ail1_list; | 148 | struct list_head *head = &sdp->sd_ail1_list; |
148 | u64 sync_gen; | 149 | u64 sync_gen; |
@@ -261,6 +262,12 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
261 | * @sdp: The GFS2 superblock | 262 | * @sdp: The GFS2 superblock |
262 | * @blks: The number of blocks to reserve | 263 | * @blks: The number of blocks to reserve |
263 | * | 264 | * |
265 | * Note that we never give out the last 6 blocks of the journal. Thats | ||
266 | * due to the fact that there is are a small number of header blocks | ||
267 | * associated with each log flush. The exact number can't be known until | ||
268 | * flush time, so we ensure that we have just enough free blocks at all | ||
269 | * times to avoid running out during a log flush. | ||
270 | * | ||
264 | * Returns: errno | 271 | * Returns: errno |
265 | */ | 272 | */ |
266 | 273 | ||
@@ -274,7 +281,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
274 | 281 | ||
275 | mutex_lock(&sdp->sd_log_reserve_mutex); | 282 | mutex_lock(&sdp->sd_log_reserve_mutex); |
276 | gfs2_log_lock(sdp); | 283 | gfs2_log_lock(sdp); |
277 | while(sdp->sd_log_blks_free <= blks) { | 284 | while(sdp->sd_log_blks_free <= (blks + 6)) { |
278 | gfs2_log_unlock(sdp); | 285 | gfs2_log_unlock(sdp); |
279 | gfs2_ail1_empty(sdp, 0); | 286 | gfs2_ail1_empty(sdp, 0); |
280 | gfs2_log_flush(sdp, NULL); | 287 | gfs2_log_flush(sdp, NULL); |
@@ -319,7 +326,8 @@ static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | |||
319 | bh_map.b_size = 1 << inode->i_blkbits; | 326 | bh_map.b_size = 1 << inode->i_blkbits; |
320 | error = gfs2_block_map(inode, lbn, 0, &bh_map); | 327 | error = gfs2_block_map(inode, lbn, 0, &bh_map); |
321 | if (error || !bh_map.b_blocknr) | 328 | if (error || !bh_map.b_blocknr) |
322 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); | 329 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, |
330 | (unsigned long long)bh_map.b_blocknr, lbn); | ||
323 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); | 331 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); |
324 | 332 | ||
325 | return bh_map.b_blocknr; | 333 | return bh_map.b_blocknr; |
@@ -643,12 +651,9 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
643 | up_read(&sdp->sd_log_flush_lock); | 651 | up_read(&sdp->sd_log_flush_lock); |
644 | 652 | ||
645 | gfs2_log_lock(sdp); | 653 | gfs2_log_lock(sdp); |
646 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) { | 654 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) |
647 | gfs2_log_unlock(sdp); | 655 | wake_up_process(sdp->sd_logd_process); |
648 | gfs2_log_flush(sdp, NULL); | 656 | gfs2_log_unlock(sdp); |
649 | } else { | ||
650 | gfs2_log_unlock(sdp); | ||
651 | } | ||
652 | } | 657 | } |
653 | 658 | ||
654 | /** | 659 | /** |
@@ -686,3 +691,21 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
686 | up_write(&sdp->sd_log_flush_lock); | 691 | up_write(&sdp->sd_log_flush_lock); |
687 | } | 692 | } |
688 | 693 | ||
694 | |||
695 | /** | ||
696 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
697 | * @sdp: the filesystem | ||
698 | * | ||
699 | */ | ||
700 | |||
701 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
702 | { | ||
703 | gfs2_log_flush(sdp, NULL); | ||
704 | for (;;) { | ||
705 | gfs2_ail1_start(sdp, DIO_ALL); | ||
706 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
707 | break; | ||
708 | msleep(10); | ||
709 | } | ||
710 | } | ||
711 | |||
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 7f5737d55612..8e7aa0f29109 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -48,7 +48,6 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp, | |||
48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | 48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
49 | unsigned int ssize); | 49 | unsigned int ssize); |
50 | 50 | ||
51 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags); | ||
52 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); | 51 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); |
53 | 52 | ||
54 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
@@ -61,5 +60,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | |||
61 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 60 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
62 | 61 | ||
63 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 62 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
63 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
64 | 64 | ||
65 | #endif /* __LOG_DOT_H__ */ | 65 | #endif /* __LOG_DOT_H__ */ |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index ab6d1115f95d..4d7f94d8c7bd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -182,7 +182,7 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, | 184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, |
185 | struct gfs2_log_header *head, int pass) | 185 | struct gfs2_log_header_host *head, int pass) |
186 | { | 186 | { |
187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
188 | 188 | ||
@@ -328,7 +328,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, | 330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, |
331 | struct gfs2_log_header *head, int pass) | 331 | struct gfs2_log_header_host *head, int pass) |
332 | { | 332 | { |
333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
334 | 334 | ||
@@ -509,7 +509,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
509 | { | 509 | { |
510 | LIST_HEAD(started); | 510 | LIST_HEAD(started); |
511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; | 511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; |
512 | struct buffer_head *bh = NULL; | 512 | struct buffer_head *bh = NULL,*bh1 = NULL; |
513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | 513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); |
514 | struct gfs2_log_descriptor *ld; | 514 | struct gfs2_log_descriptor *ld; |
515 | unsigned int limit; | 515 | unsigned int limit; |
@@ -537,8 +537,13 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
537 | list_for_each_entry_safe_continue(bd1, bdt, | 537 | list_for_each_entry_safe_continue(bd1, bdt, |
538 | &sdp->sd_log_le_databuf, | 538 | &sdp->sd_log_le_databuf, |
539 | bd_le.le_list) { | 539 | bd_le.le_list) { |
540 | /* store off the buffer head in a local ptr since | ||
541 | * gfs2_bufdata might change when we drop the log lock | ||
542 | */ | ||
543 | bh1 = bd1->bd_bh; | ||
544 | |||
540 | /* An ordered write buffer */ | 545 | /* An ordered write buffer */ |
541 | if (bd1->bd_bh && !buffer_pinned(bd1->bd_bh)) { | 546 | if (bh1 && !buffer_pinned(bh1)) { |
542 | list_move(&bd1->bd_le.le_list, &started); | 547 | list_move(&bd1->bd_le.le_list, &started); |
543 | if (bd1 == bd2) { | 548 | if (bd1 == bd2) { |
544 | bd2 = NULL; | 549 | bd2 = NULL; |
@@ -547,20 +552,21 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
547 | bd_le.le_list); | 552 | bd_le.le_list); |
548 | } | 553 | } |
549 | total_dbuf--; | 554 | total_dbuf--; |
550 | if (bd1->bd_bh) { | 555 | if (bh1) { |
551 | get_bh(bd1->bd_bh); | 556 | if (buffer_dirty(bh1)) { |
552 | if (buffer_dirty(bd1->bd_bh)) { | 557 | get_bh(bh1); |
558 | |||
553 | gfs2_log_unlock(sdp); | 559 | gfs2_log_unlock(sdp); |
554 | wait_on_buffer(bd1->bd_bh); | 560 | |
555 | ll_rw_block(WRITE, 1, | 561 | ll_rw_block(SWRITE, 1, &bh1); |
556 | &bd1->bd_bh); | 562 | brelse(bh1); |
563 | |||
557 | gfs2_log_lock(sdp); | 564 | gfs2_log_lock(sdp); |
558 | } | 565 | } |
559 | brelse(bd1->bd_bh); | ||
560 | continue; | 566 | continue; |
561 | } | 567 | } |
562 | continue; | 568 | continue; |
563 | } else if (bd1->bd_bh) { /* A journaled buffer */ | 569 | } else if (bh1) { /* A journaled buffer */ |
564 | int magic; | 570 | int magic; |
565 | gfs2_log_unlock(sdp); | 571 | gfs2_log_unlock(sdp); |
566 | if (!bh) { | 572 | if (!bh) { |
@@ -582,16 +588,16 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
582 | ld->ld_data2 = cpu_to_be32(0); | 588 | ld->ld_data2 = cpu_to_be32(0); |
583 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); | 589 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); |
584 | } | 590 | } |
585 | magic = gfs2_check_magic(bd1->bd_bh); | 591 | magic = gfs2_check_magic(bh1); |
586 | *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); | 592 | *ptr++ = cpu_to_be64(bh1->b_blocknr); |
587 | *ptr++ = cpu_to_be64((__u64)magic); | 593 | *ptr++ = cpu_to_be64((__u64)magic); |
588 | clear_buffer_escaped(bd1->bd_bh); | 594 | clear_buffer_escaped(bh1); |
589 | if (unlikely(magic != 0)) | 595 | if (unlikely(magic != 0)) |
590 | set_buffer_escaped(bd1->bd_bh); | 596 | set_buffer_escaped(bh1); |
591 | gfs2_log_lock(sdp); | 597 | gfs2_log_lock(sdp); |
592 | if (n++ > num) | 598 | if (n++ > num) |
593 | break; | 599 | break; |
594 | } else if (!bd1->bd_bh) { | 600 | } else if (!bh1) { |
595 | total_dbuf--; | 601 | total_dbuf--; |
596 | sdp->sd_log_num_databuf--; | 602 | sdp->sd_log_num_databuf--; |
597 | list_del_init(&bd1->bd_le.le_list); | 603 | list_del_init(&bd1->bd_le.le_list); |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 5839c05ae6be..965bc65c7c64 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -60,7 +60,7 @@ static inline void lops_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, | 62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, |
63 | struct gfs2_log_header *head, | 63 | struct gfs2_log_header_host *head, |
64 | unsigned int pass) | 64 | unsigned int pass) |
65 | { | 65 | { |
66 | int x; | 66 | int x; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 9889c1eacec1..7c1a9e22a526 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "util.h" | 25 | #include "util.h" |
26 | #include "glock.h" | 26 | #include "glock.h" |
27 | 27 | ||
28 | static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 28 | static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
29 | { | 29 | { |
30 | struct gfs2_inode *ip = foo; | 30 | struct gfs2_inode *ip = foo; |
31 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 31 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
@@ -37,7 +37,7 @@ static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long | |||
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | static void gfs2_init_glock_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 40 | static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
41 | { | 41 | { |
42 | struct gfs2_glock *gl = foo; | 42 | struct gfs2_glock *gl = foo; |
43 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 43 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 3912d6a4b1e6..0e34d9918973 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -127,17 +127,17 @@ void gfs2_meta_sync(struct gfs2_glock *gl) | |||
127 | 127 | ||
128 | /** | 128 | /** |
129 | * getbuf - Get a buffer with a given address space | 129 | * getbuf - Get a buffer with a given address space |
130 | * @sdp: the filesystem | 130 | * @gl: the glock |
131 | * @aspace: the address space | ||
132 | * @blkno: the block number (filesystem scope) | 131 | * @blkno: the block number (filesystem scope) |
133 | * @create: 1 if the buffer should be created | 132 | * @create: 1 if the buffer should be created |
134 | * | 133 | * |
135 | * Returns: the buffer | 134 | * Returns: the buffer |
136 | */ | 135 | */ |
137 | 136 | ||
138 | static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | 137 | static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create) |
139 | u64 blkno, int create) | ||
140 | { | 138 | { |
139 | struct address_space *mapping = gl->gl_aspace->i_mapping; | ||
140 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
141 | struct page *page; | 141 | struct page *page; |
142 | struct buffer_head *bh; | 142 | struct buffer_head *bh; |
143 | unsigned int shift; | 143 | unsigned int shift; |
@@ -150,13 +150,13 @@ static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | |||
150 | 150 | ||
151 | if (create) { | 151 | if (create) { |
152 | for (;;) { | 152 | for (;;) { |
153 | page = grab_cache_page(aspace->i_mapping, index); | 153 | page = grab_cache_page(mapping, index); |
154 | if (page) | 154 | if (page) |
155 | break; | 155 | break; |
156 | yield(); | 156 | yield(); |
157 | } | 157 | } |
158 | } else { | 158 | } else { |
159 | page = find_lock_page(aspace->i_mapping, index); | 159 | page = find_lock_page(mapping, index); |
160 | if (!page) | 160 | if (!page) |
161 | return NULL; | 161 | return NULL; |
162 | } | 162 | } |
@@ -202,7 +202,7 @@ static void meta_prep_new(struct buffer_head *bh) | |||
202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | 202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) |
203 | { | 203 | { |
204 | struct buffer_head *bh; | 204 | struct buffer_head *bh; |
205 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 205 | bh = getbuf(gl, blkno, CREATE); |
206 | meta_prep_new(bh); | 206 | meta_prep_new(bh); |
207 | return bh; | 207 | return bh; |
208 | } | 208 | } |
@@ -220,7 +220,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
221 | struct buffer_head **bhp) | 221 | struct buffer_head **bhp) |
222 | { | 222 | { |
223 | *bhp = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 223 | *bhp = getbuf(gl, blkno, CREATE); |
224 | if (!buffer_uptodate(*bhp)) | 224 | if (!buffer_uptodate(*bhp)) |
225 | ll_rw_block(READ_META, 1, bhp); | 225 | ll_rw_block(READ_META, 1, bhp); |
226 | if (flags & DIO_WAIT) { | 226 | if (flags & DIO_WAIT) { |
@@ -379,11 +379,10 @@ void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | 379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) |
380 | { | 380 | { |
381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
382 | struct inode *aspace = ip->i_gl->gl_aspace; | ||
383 | struct buffer_head *bh; | 382 | struct buffer_head *bh; |
384 | 383 | ||
385 | while (blen) { | 384 | while (blen) { |
386 | bh = getbuf(sdp, aspace, bstart, NO_CREATE); | 385 | bh = getbuf(ip->i_gl, bstart, NO_CREATE); |
387 | if (bh) { | 386 | if (bh) { |
388 | struct gfs2_bufdata *bd = bh->b_private; | 387 | struct gfs2_bufdata *bd = bh->b_private; |
389 | 388 | ||
@@ -472,6 +471,9 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
472 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 471 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; |
473 | int in_cache = 0; | 472 | int in_cache = 0; |
474 | 473 | ||
474 | BUG_ON(!gl); | ||
475 | BUG_ON(!sdp); | ||
476 | |||
475 | spin_lock(&ip->i_spin); | 477 | spin_lock(&ip->i_spin); |
476 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { | 478 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { |
477 | bh = *bh_slot; | 479 | bh = *bh_slot; |
@@ -481,7 +483,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
481 | spin_unlock(&ip->i_spin); | 483 | spin_unlock(&ip->i_spin); |
482 | 484 | ||
483 | if (!bh) | 485 | if (!bh) |
484 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, num, CREATE); | 486 | bh = getbuf(gl, num, CREATE); |
485 | 487 | ||
486 | if (!bh) | 488 | if (!bh) |
487 | return -ENOBUFS; | 489 | return -ENOBUFS; |
@@ -532,7 +534,6 @@ err: | |||
532 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | 534 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) |
533 | { | 535 | { |
534 | struct gfs2_sbd *sdp = gl->gl_sbd; | 536 | struct gfs2_sbd *sdp = gl->gl_sbd; |
535 | struct inode *aspace = gl->gl_aspace; | ||
536 | struct buffer_head *first_bh, *bh; | 537 | struct buffer_head *first_bh, *bh; |
537 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> | 538 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> |
538 | sdp->sd_sb.sb_bsize_shift; | 539 | sdp->sd_sb.sb_bsize_shift; |
@@ -544,7 +545,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
544 | if (extlen > max_ra) | 545 | if (extlen > max_ra) |
545 | extlen = max_ra; | 546 | extlen = max_ra; |
546 | 547 | ||
547 | first_bh = getbuf(sdp, aspace, dblock, CREATE); | 548 | first_bh = getbuf(gl, dblock, CREATE); |
548 | 549 | ||
549 | if (buffer_uptodate(first_bh)) | 550 | if (buffer_uptodate(first_bh)) |
550 | goto out; | 551 | goto out; |
@@ -555,7 +556,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
555 | extlen--; | 556 | extlen--; |
556 | 557 | ||
557 | while (extlen) { | 558 | while (extlen) { |
558 | bh = getbuf(sdp, aspace, dblock, CREATE); | 559 | bh = getbuf(gl, dblock, CREATE); |
559 | 560 | ||
560 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) | 561 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) |
561 | ll_rw_block(READA, 1, &bh); | 562 | ll_rw_block(READA, 1, &bh); |
@@ -571,20 +572,3 @@ out: | |||
571 | return first_bh; | 572 | return first_bh; |
572 | } | 573 | } |
573 | 574 | ||
574 | /** | ||
575 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
576 | * @sdp: the filesystem | ||
577 | * | ||
578 | */ | ||
579 | |||
580 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
581 | { | ||
582 | gfs2_log_flush(sdp, NULL); | ||
583 | for (;;) { | ||
584 | gfs2_ail1_start(sdp, DIO_ALL); | ||
585 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
586 | break; | ||
587 | msleep(10); | ||
588 | } | ||
589 | } | ||
590 | |||
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index 3ec939e20dff..e037425bc042 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -67,7 +67,6 @@ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, | |||
67 | } | 67 | } |
68 | 68 | ||
69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); | 69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); |
70 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
71 | 70 | ||
72 | #define buffer_busy(bh) \ | 71 | #define buffer_busy(bh) \ |
73 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) | 72 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) |
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c index 1025960b0e6e..f2495f1e21ad 100644 --- a/fs/gfs2/ondisk.c +++ b/fs/gfs2/ondisk.c | |||
@@ -15,6 +15,8 @@ | |||
15 | 15 | ||
16 | #include "gfs2.h" | 16 | #include "gfs2.h" |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/lm_interface.h> | ||
19 | #include "incore.h" | ||
18 | 20 | ||
19 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ | 21 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ |
20 | struct->member); | 22 | struct->member); |
@@ -32,7 +34,7 @@ | |||
32 | * first arg: the cpu-order structure | 34 | * first arg: the cpu-order structure |
33 | */ | 35 | */ |
34 | 36 | ||
35 | void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | 37 | void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf) |
36 | { | 38 | { |
37 | const struct gfs2_inum *str = buf; | 39 | const struct gfs2_inum *str = buf; |
38 | 40 | ||
@@ -40,7 +42,7 @@ void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | |||
40 | no->no_addr = be64_to_cpu(str->no_addr); | 42 | no->no_addr = be64_to_cpu(str->no_addr); |
41 | } | 43 | } |
42 | 44 | ||
43 | void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | 45 | void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf) |
44 | { | 46 | { |
45 | struct gfs2_inum *str = buf; | 47 | struct gfs2_inum *str = buf; |
46 | 48 | ||
@@ -48,13 +50,13 @@ void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | |||
48 | str->no_addr = cpu_to_be64(no->no_addr); | 50 | str->no_addr = cpu_to_be64(no->no_addr); |
49 | } | 51 | } |
50 | 52 | ||
51 | static void gfs2_inum_print(const struct gfs2_inum *no) | 53 | static void gfs2_inum_print(const struct gfs2_inum_host *no) |
52 | { | 54 | { |
53 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); | 55 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); |
54 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); | 56 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); |
55 | } | 57 | } |
56 | 58 | ||
57 | static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | 59 | static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) |
58 | { | 60 | { |
59 | const struct gfs2_meta_header *str = buf; | 61 | const struct gfs2_meta_header *str = buf; |
60 | 62 | ||
@@ -63,23 +65,7 @@ static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | |||
63 | mh->mh_format = be32_to_cpu(str->mh_format); | 65 | mh->mh_format = be32_to_cpu(str->mh_format); |
64 | } | 66 | } |
65 | 67 | ||
66 | static void gfs2_meta_header_out(const struct gfs2_meta_header *mh, void *buf) | 68 | void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) |
67 | { | ||
68 | struct gfs2_meta_header *str = buf; | ||
69 | |||
70 | str->mh_magic = cpu_to_be32(mh->mh_magic); | ||
71 | str->mh_type = cpu_to_be32(mh->mh_type); | ||
72 | str->mh_format = cpu_to_be32(mh->mh_format); | ||
73 | } | ||
74 | |||
75 | static void gfs2_meta_header_print(const struct gfs2_meta_header *mh) | ||
76 | { | ||
77 | pv(mh, mh_magic, "0x%.8X"); | ||
78 | pv(mh, mh_type, "%u"); | ||
79 | pv(mh, mh_format, "%u"); | ||
80 | } | ||
81 | |||
82 | void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | ||
83 | { | 69 | { |
84 | const struct gfs2_sb *str = buf; | 70 | const struct gfs2_sb *str = buf; |
85 | 71 | ||
@@ -97,7 +83,7 @@ void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | |||
97 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | 83 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); |
98 | } | 84 | } |
99 | 85 | ||
100 | void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | 86 | void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf) |
101 | { | 87 | { |
102 | const struct gfs2_rindex *str = buf; | 88 | const struct gfs2_rindex *str = buf; |
103 | 89 | ||
@@ -109,7 +95,7 @@ void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | |||
109 | 95 | ||
110 | } | 96 | } |
111 | 97 | ||
112 | void gfs2_rindex_print(const struct gfs2_rindex *ri) | 98 | void gfs2_rindex_print(const struct gfs2_rindex_host *ri) |
113 | { | 99 | { |
114 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); | 100 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); |
115 | pv(ri, ri_length, "%u"); | 101 | pv(ri, ri_length, "%u"); |
@@ -120,22 +106,20 @@ void gfs2_rindex_print(const struct gfs2_rindex *ri) | |||
120 | pv(ri, ri_bitbytes, "%u"); | 106 | pv(ri, ri_bitbytes, "%u"); |
121 | } | 107 | } |
122 | 108 | ||
123 | void gfs2_rgrp_in(struct gfs2_rgrp *rg, const void *buf) | 109 | void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) |
124 | { | 110 | { |
125 | const struct gfs2_rgrp *str = buf; | 111 | const struct gfs2_rgrp *str = buf; |
126 | 112 | ||
127 | gfs2_meta_header_in(&rg->rg_header, buf); | ||
128 | rg->rg_flags = be32_to_cpu(str->rg_flags); | 113 | rg->rg_flags = be32_to_cpu(str->rg_flags); |
129 | rg->rg_free = be32_to_cpu(str->rg_free); | 114 | rg->rg_free = be32_to_cpu(str->rg_free); |
130 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | 115 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); |
131 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | 116 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); |
132 | } | 117 | } |
133 | 118 | ||
134 | void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | 119 | void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) |
135 | { | 120 | { |
136 | struct gfs2_rgrp *str = buf; | 121 | struct gfs2_rgrp *str = buf; |
137 | 122 | ||
138 | gfs2_meta_header_out(&rg->rg_header, buf); | ||
139 | str->rg_flags = cpu_to_be32(rg->rg_flags); | 123 | str->rg_flags = cpu_to_be32(rg->rg_flags); |
140 | str->rg_free = cpu_to_be32(rg->rg_free); | 124 | str->rg_free = cpu_to_be32(rg->rg_free); |
141 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | 125 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); |
@@ -144,7 +128,7 @@ void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | |||
144 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 128 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
145 | } | 129 | } |
146 | 130 | ||
147 | void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | 131 | void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) |
148 | { | 132 | { |
149 | const struct gfs2_quota *str = buf; | 133 | const struct gfs2_quota *str = buf; |
150 | 134 | ||
@@ -153,96 +137,56 @@ void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | |||
153 | qu->qu_value = be64_to_cpu(str->qu_value); | 137 | qu->qu_value = be64_to_cpu(str->qu_value); |
154 | } | 138 | } |
155 | 139 | ||
156 | void gfs2_dinode_in(struct gfs2_dinode *di, const void *buf) | 140 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
157 | { | ||
158 | const struct gfs2_dinode *str = buf; | ||
159 | |||
160 | gfs2_meta_header_in(&di->di_header, buf); | ||
161 | gfs2_inum_in(&di->di_num, &str->di_num); | ||
162 | |||
163 | di->di_mode = be32_to_cpu(str->di_mode); | ||
164 | di->di_uid = be32_to_cpu(str->di_uid); | ||
165 | di->di_gid = be32_to_cpu(str->di_gid); | ||
166 | di->di_nlink = be32_to_cpu(str->di_nlink); | ||
167 | di->di_size = be64_to_cpu(str->di_size); | ||
168 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
169 | di->di_atime = be64_to_cpu(str->di_atime); | ||
170 | di->di_mtime = be64_to_cpu(str->di_mtime); | ||
171 | di->di_ctime = be64_to_cpu(str->di_ctime); | ||
172 | di->di_major = be32_to_cpu(str->di_major); | ||
173 | di->di_minor = be32_to_cpu(str->di_minor); | ||
174 | |||
175 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
176 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
177 | di->di_generation = be64_to_cpu(str->di_generation); | ||
178 | |||
179 | di->di_flags = be32_to_cpu(str->di_flags); | ||
180 | di->di_payload_format = be32_to_cpu(str->di_payload_format); | ||
181 | di->di_height = be16_to_cpu(str->di_height); | ||
182 | |||
183 | di->di_depth = be16_to_cpu(str->di_depth); | ||
184 | di->di_entries = be32_to_cpu(str->di_entries); | ||
185 | |||
186 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
187 | |||
188 | } | ||
189 | |||
190 | void gfs2_dinode_out(const struct gfs2_dinode *di, void *buf) | ||
191 | { | 141 | { |
142 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
192 | struct gfs2_dinode *str = buf; | 143 | struct gfs2_dinode *str = buf; |
193 | 144 | ||
194 | gfs2_meta_header_out(&di->di_header, buf); | 145 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
195 | gfs2_inum_out(&di->di_num, (char *)&str->di_num); | 146 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); |
147 | str->di_header.__pad0 = 0; | ||
148 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
149 | str->di_header.__pad1 = 0; | ||
196 | 150 | ||
197 | str->di_mode = cpu_to_be32(di->di_mode); | 151 | gfs2_inum_out(&ip->i_num, &str->di_num); |
198 | str->di_uid = cpu_to_be32(di->di_uid); | 152 | |
199 | str->di_gid = cpu_to_be32(di->di_gid); | 153 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
200 | str->di_nlink = cpu_to_be32(di->di_nlink); | 154 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
155 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
156 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
201 | str->di_size = cpu_to_be64(di->di_size); | 157 | str->di_size = cpu_to_be64(di->di_size); |
202 | str->di_blocks = cpu_to_be64(di->di_blocks); | 158 | str->di_blocks = cpu_to_be64(di->di_blocks); |
203 | str->di_atime = cpu_to_be64(di->di_atime); | 159 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
204 | str->di_mtime = cpu_to_be64(di->di_mtime); | 160 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
205 | str->di_ctime = cpu_to_be64(di->di_ctime); | 161 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
206 | str->di_major = cpu_to_be32(di->di_major); | ||
207 | str->di_minor = cpu_to_be32(di->di_minor); | ||
208 | 162 | ||
209 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | 163 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); |
210 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | 164 | str->di_goal_data = cpu_to_be64(di->di_goal_data); |
211 | str->di_generation = cpu_to_be64(di->di_generation); | 165 | str->di_generation = cpu_to_be64(di->di_generation); |
212 | 166 | ||
213 | str->di_flags = cpu_to_be32(di->di_flags); | 167 | str->di_flags = cpu_to_be32(di->di_flags); |
214 | str->di_payload_format = cpu_to_be32(di->di_payload_format); | ||
215 | str->di_height = cpu_to_be16(di->di_height); | 168 | str->di_height = cpu_to_be16(di->di_height); |
216 | 169 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | |
170 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | ||
171 | GFS2_FORMAT_DE : 0); | ||
217 | str->di_depth = cpu_to_be16(di->di_depth); | 172 | str->di_depth = cpu_to_be16(di->di_depth); |
218 | str->di_entries = cpu_to_be32(di->di_entries); | 173 | str->di_entries = cpu_to_be32(di->di_entries); |
219 | 174 | ||
220 | str->di_eattr = cpu_to_be64(di->di_eattr); | 175 | str->di_eattr = cpu_to_be64(di->di_eattr); |
221 | |||
222 | } | 176 | } |
223 | 177 | ||
224 | void gfs2_dinode_print(const struct gfs2_dinode *di) | 178 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
225 | { | 179 | { |
226 | gfs2_meta_header_print(&di->di_header); | 180 | const struct gfs2_dinode_host *di = &ip->i_di; |
227 | gfs2_inum_print(&di->di_num); | 181 | |
182 | gfs2_inum_print(&ip->i_num); | ||
228 | 183 | ||
229 | pv(di, di_mode, "0%o"); | ||
230 | pv(di, di_uid, "%u"); | ||
231 | pv(di, di_gid, "%u"); | ||
232 | pv(di, di_nlink, "%u"); | ||
233 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 184 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); |
234 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); | 185 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); |
235 | printk(KERN_INFO " di_atime = %lld\n", (long long)di->di_atime); | ||
236 | printk(KERN_INFO " di_mtime = %lld\n", (long long)di->di_mtime); | ||
237 | printk(KERN_INFO " di_ctime = %lld\n", (long long)di->di_ctime); | ||
238 | pv(di, di_major, "%u"); | ||
239 | pv(di, di_minor, "%u"); | ||
240 | |||
241 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); | 186 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); |
242 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); | 187 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); |
243 | 188 | ||
244 | pv(di, di_flags, "0x%.8X"); | 189 | pv(di, di_flags, "0x%.8X"); |
245 | pv(di, di_payload_format, "%u"); | ||
246 | pv(di, di_height, "%u"); | 190 | pv(di, di_height, "%u"); |
247 | 191 | ||
248 | pv(di, di_depth, "%u"); | 192 | pv(di, di_depth, "%u"); |
@@ -251,7 +195,7 @@ void gfs2_dinode_print(const struct gfs2_dinode *di) | |||
251 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); | 195 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); |
252 | } | 196 | } |
253 | 197 | ||
254 | void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | 198 | void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) |
255 | { | 199 | { |
256 | const struct gfs2_log_header *str = buf; | 200 | const struct gfs2_log_header *str = buf; |
257 | 201 | ||
@@ -263,7 +207,7 @@ void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | |||
263 | lh->lh_hash = be32_to_cpu(str->lh_hash); | 207 | lh->lh_hash = be32_to_cpu(str->lh_hash); |
264 | } | 208 | } |
265 | 209 | ||
266 | void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | 210 | void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) |
267 | { | 211 | { |
268 | const struct gfs2_inum_range *str = buf; | 212 | const struct gfs2_inum_range *str = buf; |
269 | 213 | ||
@@ -271,7 +215,7 @@ void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | |||
271 | ir->ir_length = be64_to_cpu(str->ir_length); | 215 | ir->ir_length = be64_to_cpu(str->ir_length); |
272 | } | 216 | } |
273 | 217 | ||
274 | void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | 218 | void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) |
275 | { | 219 | { |
276 | struct gfs2_inum_range *str = buf; | 220 | struct gfs2_inum_range *str = buf; |
277 | 221 | ||
@@ -279,7 +223,7 @@ void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | |||
279 | str->ir_length = cpu_to_be64(ir->ir_length); | 223 | str->ir_length = cpu_to_be64(ir->ir_length); |
280 | } | 224 | } |
281 | 225 | ||
282 | void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | 226 | void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) |
283 | { | 227 | { |
284 | const struct gfs2_statfs_change *str = buf; | 228 | const struct gfs2_statfs_change *str = buf; |
285 | 229 | ||
@@ -288,7 +232,7 @@ void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | |||
288 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | 232 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); |
289 | } | 233 | } |
290 | 234 | ||
291 | void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | 235 | void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) |
292 | { | 236 | { |
293 | struct gfs2_statfs_change *str = buf; | 237 | struct gfs2_statfs_change *str = buf; |
294 | 238 | ||
@@ -297,7 +241,7 @@ void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | |||
297 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | 241 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); |
298 | } | 242 | } |
299 | 243 | ||
300 | void gfs2_quota_change_in(struct gfs2_quota_change *qc, const void *buf) | 244 | void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) |
301 | { | 245 | { |
302 | const struct gfs2_quota_change *str = buf; | 246 | const struct gfs2_quota_change *str = buf; |
303 | 247 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 015640b3f123..d8d69a72a10d 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -156,19 +156,6 @@ out_ignore: | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int zero_readpage(struct page *page) | ||
160 | { | ||
161 | void *kaddr; | ||
162 | |||
163 | kaddr = kmap_atomic(page, KM_USER0); | ||
164 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
165 | kunmap_atomic(kaddr, KM_USER0); | ||
166 | |||
167 | SetPageUptodate(page); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /** | 159 | /** |
173 | * stuffed_readpage - Fill in a Linux page with stuffed file data | 160 | * stuffed_readpage - Fill in a Linux page with stuffed file data |
174 | * @ip: the inode | 161 | * @ip: the inode |
@@ -183,9 +170,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
183 | void *kaddr; | 170 | void *kaddr; |
184 | int error; | 171 | int error; |
185 | 172 | ||
186 | /* Only the first page of a stuffed file might contain data */ | 173 | BUG_ON(page->index); |
187 | if (unlikely(page->index)) | ||
188 | return zero_readpage(page); | ||
189 | 174 | ||
190 | error = gfs2_meta_inode_buffer(ip, &dibh); | 175 | error = gfs2_meta_inode_buffer(ip, &dibh); |
191 | if (error) | 176 | if (error) |
@@ -230,9 +215,9 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
230 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ | 215 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ |
231 | goto skip_lock; | 216 | goto skip_lock; |
232 | } | 217 | } |
233 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); | 218 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); |
234 | do_unlock = 1; | 219 | do_unlock = 1; |
235 | error = gfs2_glock_nq_m_atime(1, &gh); | 220 | error = gfs2_glock_nq_atime(&gh); |
236 | if (unlikely(error)) | 221 | if (unlikely(error)) |
237 | goto out_unlock; | 222 | goto out_unlock; |
238 | } | 223 | } |
@@ -254,6 +239,8 @@ skip_lock: | |||
254 | out: | 239 | out: |
255 | return error; | 240 | return error; |
256 | out_unlock: | 241 | out_unlock: |
242 | if (error == GLR_TRYFAILED) | ||
243 | error = AOP_TRUNCATED_PAGE; | ||
257 | unlock_page(page); | 244 | unlock_page(page); |
258 | if (do_unlock) | 245 | if (do_unlock) |
259 | gfs2_holder_uninit(&gh); | 246 | gfs2_holder_uninit(&gh); |
@@ -293,9 +280,9 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, | |||
293 | goto skip_lock; | 280 | goto skip_lock; |
294 | } | 281 | } |
295 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, | 282 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, |
296 | LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); | 283 | LM_FLAG_TRY_1CB|GL_ATIME, &gh); |
297 | do_unlock = 1; | 284 | do_unlock = 1; |
298 | ret = gfs2_glock_nq_m_atime(1, &gh); | 285 | ret = gfs2_glock_nq_atime(&gh); |
299 | if (ret == GLR_TRYFAILED) | 286 | if (ret == GLR_TRYFAILED) |
300 | goto out_noerror; | 287 | goto out_noerror; |
301 | if (unlikely(ret)) | 288 | if (unlikely(ret)) |
@@ -366,10 +353,13 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
366 | unsigned int write_len = to - from; | 353 | unsigned int write_len = to - from; |
367 | 354 | ||
368 | 355 | ||
369 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh); | 356 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh); |
370 | error = gfs2_glock_nq_m_atime(1, &ip->i_gh); | 357 | error = gfs2_glock_nq_atime(&ip->i_gh); |
371 | if (error) | 358 | if (unlikely(error)) { |
359 | if (error == GLR_TRYFAILED) | ||
360 | error = AOP_TRUNCATED_PAGE; | ||
372 | goto out_uninit; | 361 | goto out_uninit; |
362 | } | ||
373 | 363 | ||
374 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); | 364 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); |
375 | 365 | ||
@@ -386,7 +376,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
386 | if (error) | 376 | if (error) |
387 | goto out_alloc_put; | 377 | goto out_alloc_put; |
388 | 378 | ||
389 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 379 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
390 | if (error) | 380 | if (error) |
391 | goto out_qunlock; | 381 | goto out_qunlock; |
392 | 382 | ||
@@ -482,8 +472,10 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
482 | 472 | ||
483 | SetPageUptodate(page); | 473 | SetPageUptodate(page); |
484 | 474 | ||
485 | if (inode->i_size < file_size) | 475 | if (inode->i_size < file_size) { |
486 | i_size_write(inode, file_size); | 476 | i_size_write(inode, file_size); |
477 | mark_inode_dirty(inode); | ||
478 | } | ||
487 | } else { | 479 | } else { |
488 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || | 480 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || |
489 | gfs2_is_jdata(ip)) | 481 | gfs2_is_jdata(ip)) |
@@ -498,11 +490,6 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
498 | di->di_size = cpu_to_be64(inode->i_size); | 490 | di->di_size = cpu_to_be64(inode->i_size); |
499 | } | 491 | } |
500 | 492 | ||
501 | di->di_mode = cpu_to_be32(inode->i_mode); | ||
502 | di->di_atime = cpu_to_be64(inode->i_atime.tv_sec); | ||
503 | di->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec); | ||
504 | di->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec); | ||
505 | |||
506 | brelse(dibh); | 493 | brelse(dibh); |
507 | gfs2_trans_end(sdp); | 494 | gfs2_trans_end(sdp); |
508 | if (al->al_requested) { | 495 | if (al->al_requested) { |
@@ -624,7 +611,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
624 | * on this path. All we need change is atime. | 611 | * on this path. All we need change is atime. |
625 | */ | 612 | */ |
626 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 613 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
627 | rv = gfs2_glock_nq_m_atime(1, &gh); | 614 | rv = gfs2_glock_nq_atime(&gh); |
628 | if (rv) | 615 | if (rv) |
629 | goto out; | 616 | goto out; |
630 | 617 | ||
@@ -737,6 +724,9 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
737 | if (!atomic_read(&aspace->i_writecount)) | 724 | if (!atomic_read(&aspace->i_writecount)) |
738 | return 0; | 725 | return 0; |
739 | 726 | ||
727 | if (!(gfp_mask & __GFP_WAIT)) | ||
728 | return 0; | ||
729 | |||
740 | if (time_after_eq(jiffies, t)) { | 730 | if (time_after_eq(jiffies, t)) { |
741 | stuck_releasepage(bh); | 731 | stuck_releasepage(bh); |
742 | /* should we withdraw here? */ | 732 | /* should we withdraw here? */ |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index 00041b1b8025..d355899585d8 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -43,7 +43,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
43 | struct inode *inode = dentry->d_inode; | 43 | struct inode *inode = dentry->d_inode; |
44 | struct gfs2_holder d_gh; | 44 | struct gfs2_holder d_gh; |
45 | struct gfs2_inode *ip; | 45 | struct gfs2_inode *ip; |
46 | struct gfs2_inum inum; | 46 | struct gfs2_inum_host inum; |
47 | unsigned int type; | 47 | unsigned int type; |
48 | int error; | 48 | int error; |
49 | 49 | ||
@@ -76,7 +76,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) | 76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) |
77 | goto invalid_gunlock; | 77 | goto invalid_gunlock; |
78 | 78 | ||
79 | if (IF2DT(ip->i_di.di_mode) != type) { | 79 | if (IF2DT(ip->i_inode.i_mode) != type) { |
80 | gfs2_consist_inode(dip); | 80 | gfs2_consist_inode(dip); |
81 | goto fail_gunlock; | 81 | goto fail_gunlock; |
82 | } | 82 | } |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 86127d93bd35..b4e7b8775315 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -27,15 +27,16 @@ | |||
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
30 | __u32 *fh, | 30 | __u32 *p, |
31 | int fh_len, | 31 | int fh_len, |
32 | int fh_type, | 32 | int fh_type, |
33 | int (*acceptable)(void *context, | 33 | int (*acceptable)(void *context, |
34 | struct dentry *dentry), | 34 | struct dentry *dentry), |
35 | void *context) | 35 | void *context) |
36 | { | 36 | { |
37 | __be32 *fh = (__force __be32 *)p; | ||
37 | struct gfs2_fh_obj fh_obj; | 38 | struct gfs2_fh_obj fh_obj; |
38 | struct gfs2_inum *this, parent; | 39 | struct gfs2_inum_host *this, parent; |
39 | 40 | ||
40 | if (fh_type != fh_len) | 41 | if (fh_type != fh_len) |
41 | return NULL; | 42 | return NULL; |
@@ -65,9 +66,10 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
65 | acceptable, context); | 66 | acceptable, context); |
66 | } | 67 | } |
67 | 68 | ||
68 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | 69 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, |
69 | int connectable) | 70 | int connectable) |
70 | { | 71 | { |
72 | __be32 *fh = (__force __be32 *)p; | ||
71 | struct inode *inode = dentry->d_inode; | 73 | struct inode *inode = dentry->d_inode; |
72 | struct super_block *sb = inode->i_sb; | 74 | struct super_block *sb = inode->i_sb; |
73 | struct gfs2_inode *ip = GFS2_I(inode); | 75 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -76,14 +78,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
76 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 78 | (connectable && *len < GFS2_LARGE_FH_SIZE)) |
77 | return 255; | 79 | return 255; |
78 | 80 | ||
79 | fh[0] = ip->i_num.no_formal_ino >> 32; | 81 | fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
80 | fh[0] = cpu_to_be32(fh[0]); | 82 | fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
81 | fh[1] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 83 | fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); |
82 | fh[1] = cpu_to_be32(fh[1]); | 84 | fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
83 | fh[2] = ip->i_num.no_addr >> 32; | ||
84 | fh[2] = cpu_to_be32(fh[2]); | ||
85 | fh[3] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
86 | fh[3] = cpu_to_be32(fh[3]); | ||
87 | *len = GFS2_SMALL_FH_SIZE; | 85 | *len = GFS2_SMALL_FH_SIZE; |
88 | 86 | ||
89 | if (!connectable || inode == sb->s_root->d_inode) | 87 | if (!connectable || inode == sb->s_root->d_inode) |
@@ -95,14 +93,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
95 | igrab(inode); | 93 | igrab(inode); |
96 | spin_unlock(&dentry->d_lock); | 94 | spin_unlock(&dentry->d_lock); |
97 | 95 | ||
98 | fh[4] = ip->i_num.no_formal_ino >> 32; | 96 | fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
99 | fh[4] = cpu_to_be32(fh[4]); | 97 | fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
100 | fh[5] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 98 | fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); |
101 | fh[5] = cpu_to_be32(fh[5]); | 99 | fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
102 | fh[6] = ip->i_num.no_addr >> 32; | ||
103 | fh[6] = cpu_to_be32(fh[6]); | ||
104 | fh[7] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
105 | fh[7] = cpu_to_be32(fh[7]); | ||
106 | 100 | ||
107 | fh[8] = cpu_to_be32(inode->i_mode); | 101 | fh[8] = cpu_to_be32(inode->i_mode); |
108 | fh[9] = 0; /* pad to double word */ | 102 | fh[9] = 0; /* pad to double word */ |
@@ -114,12 +108,12 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
114 | } | 108 | } |
115 | 109 | ||
116 | struct get_name_filldir { | 110 | struct get_name_filldir { |
117 | struct gfs2_inum inum; | 111 | struct gfs2_inum_host inum; |
118 | char *name; | 112 | char *name; |
119 | }; | 113 | }; |
120 | 114 | ||
121 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, | 115 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, |
122 | u64 offset, struct gfs2_inum *inum, | 116 | u64 offset, struct gfs2_inum_host *inum, |
123 | unsigned int type) | 117 | unsigned int type) |
124 | { | 118 | { |
125 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; | 119 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; |
@@ -202,7 +196,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
202 | { | 196 | { |
203 | struct gfs2_sbd *sdp = sb->s_fs_info; | 197 | struct gfs2_sbd *sdp = sb->s_fs_info; |
204 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 198 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; |
205 | struct gfs2_inum *inum = &fh_obj->this; | 199 | struct gfs2_inum_host *inum = &fh_obj->this; |
206 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 200 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
207 | struct gfs2_rgrpd *rgd; | 201 | struct gfs2_rgrpd *rgd; |
208 | struct inode *inode; | 202 | struct inode *inode; |
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h index 09aca5046fb1..f925a955b3b8 100644 --- a/fs/gfs2/ops_export.h +++ b/fs/gfs2/ops_export.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | extern struct export_operations gfs2_export_ops; | 16 | extern struct export_operations gfs2_export_ops; |
17 | struct gfs2_fh_obj { | 17 | struct gfs2_fh_obj { |
18 | struct gfs2_inum this; | 18 | struct gfs2_inum_host this; |
19 | __u32 imode; | 19 | __u32 imode; |
20 | }; | 20 | }; |
21 | 21 | ||
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 3064f133bf3c..faa07e4b97d0 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ext2_fs.h> | 22 | #include <linux/ext2_fs.h> |
23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
24 | #include <linux/lm_interface.h> | 24 | #include <linux/lm_interface.h> |
25 | #include <linux/writeback.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | 27 | ||
27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
@@ -71,7 +72,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, | |||
71 | size = count; | 72 | size = count; |
72 | 73 | ||
73 | kaddr = kmap(page); | 74 | kaddr = kmap(page); |
74 | memcpy(desc->arg.buf, kaddr + offset, size); | 75 | memcpy(desc->arg.data, kaddr + offset, size); |
75 | kunmap(page); | 76 | kunmap(page); |
76 | 77 | ||
77 | desc->count = count - size; | 78 | desc->count = count - size; |
@@ -86,7 +87,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, | |||
86 | struct inode *inode = &ip->i_inode; | 87 | struct inode *inode = &ip->i_inode; |
87 | read_descriptor_t desc; | 88 | read_descriptor_t desc; |
88 | desc.written = 0; | 89 | desc.written = 0; |
89 | desc.arg.buf = buf; | 90 | desc.arg.data = buf; |
90 | desc.count = size; | 91 | desc.count = size; |
91 | desc.error = 0; | 92 | desc.error = 0; |
92 | do_generic_mapping_read(inode->i_mapping, ra_state, | 93 | do_generic_mapping_read(inode->i_mapping, ra_state, |
@@ -139,7 +140,7 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) | |||
139 | */ | 140 | */ |
140 | 141 | ||
141 | static int filldir_func(void *opaque, const char *name, unsigned int length, | 142 | static int filldir_func(void *opaque, const char *name, unsigned int length, |
142 | u64 offset, struct gfs2_inum *inum, | 143 | u64 offset, struct gfs2_inum_host *inum, |
143 | unsigned int type) | 144 | unsigned int type) |
144 | { | 145 | { |
145 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; | 146 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; |
@@ -246,14 +247,14 @@ static const u32 gfs2_to_fsflags[32] = { | |||
246 | 247 | ||
247 | static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | 248 | static int gfs2_get_flags(struct file *filp, u32 __user *ptr) |
248 | { | 249 | { |
249 | struct inode *inode = filp->f_dentry->d_inode; | 250 | struct inode *inode = filp->f_path.dentry->d_inode; |
250 | struct gfs2_inode *ip = GFS2_I(inode); | 251 | struct gfs2_inode *ip = GFS2_I(inode); |
251 | struct gfs2_holder gh; | 252 | struct gfs2_holder gh; |
252 | int error; | 253 | int error; |
253 | u32 fsflags; | 254 | u32 fsflags; |
254 | 255 | ||
255 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 256 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
256 | error = gfs2_glock_nq_m_atime(1, &gh); | 257 | error = gfs2_glock_nq_atime(&gh); |
257 | if (error) | 258 | if (error) |
258 | return error; | 259 | return error; |
259 | 260 | ||
@@ -266,6 +267,24 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
266 | return error; | 267 | return error; |
267 | } | 268 | } |
268 | 269 | ||
270 | void gfs2_set_inode_flags(struct inode *inode) | ||
271 | { | ||
272 | struct gfs2_inode *ip = GFS2_I(inode); | ||
273 | struct gfs2_dinode_host *di = &ip->i_di; | ||
274 | unsigned int flags = inode->i_flags; | ||
275 | |||
276 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
277 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
278 | flags |= S_IMMUTABLE; | ||
279 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
280 | flags |= S_APPEND; | ||
281 | if (di->di_flags & GFS2_DIF_NOATIME) | ||
282 | flags |= S_NOATIME; | ||
283 | if (di->di_flags & GFS2_DIF_SYNC) | ||
284 | flags |= S_SYNC; | ||
285 | inode->i_flags = flags; | ||
286 | } | ||
287 | |||
269 | /* Flags that can be set by user space */ | 288 | /* Flags that can be set by user space */ |
270 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 289 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
271 | GFS2_DIF_DIRECTIO| \ | 290 | GFS2_DIF_DIRECTIO| \ |
@@ -286,7 +305,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
286 | */ | 305 | */ |
287 | static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | 306 | static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) |
288 | { | 307 | { |
289 | struct inode *inode = filp->f_dentry->d_inode; | 308 | struct inode *inode = filp->f_path.dentry->d_inode; |
290 | struct gfs2_inode *ip = GFS2_I(inode); | 309 | struct gfs2_inode *ip = GFS2_I(inode); |
291 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 310 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
292 | struct buffer_head *bh; | 311 | struct buffer_head *bh; |
@@ -336,8 +355,9 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
336 | goto out_trans_end; | 355 | goto out_trans_end; |
337 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 356 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
338 | ip->i_di.di_flags = new_flags; | 357 | ip->i_di.di_flags = new_flags; |
339 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 358 | gfs2_dinode_out(ip, bh->b_data); |
340 | brelse(bh); | 359 | brelse(bh); |
360 | gfs2_set_inode_flags(inode); | ||
341 | out_trans_end: | 361 | out_trans_end: |
342 | gfs2_trans_end(sdp); | 362 | gfs2_trans_end(sdp); |
343 | out: | 363 | out: |
@@ -425,7 +445,7 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
425 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 445 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
426 | file->private_data = fp; | 446 | file->private_data = fp; |
427 | 447 | ||
428 | if (S_ISREG(ip->i_di.di_mode)) { | 448 | if (S_ISREG(ip->i_inode.i_mode)) { |
429 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 449 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
430 | &i_gh); | 450 | &i_gh); |
431 | if (error) | 451 | if (error) |
@@ -484,16 +504,40 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
484 | * @file: the file that points to the dentry (we ignore this) | 504 | * @file: the file that points to the dentry (we ignore this) |
485 | * @dentry: the dentry that points to the inode to sync | 505 | * @dentry: the dentry that points to the inode to sync |
486 | * | 506 | * |
507 | * The VFS will flush "normal" data for us. We only need to worry | ||
508 | * about metadata here. For journaled data, we just do a log flush | ||
509 | * as we can't avoid it. Otherwise we can just bale out if datasync | ||
510 | * is set. For stuffed inodes we must flush the log in order to | ||
511 | * ensure that all data is on disk. | ||
512 | * | ||
513 | * The call to write_inode_now() is there to write back metadata and | ||
514 | * the inode itself. It does also try and write the data, but thats | ||
515 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | ||
516 | * for us. | ||
517 | * | ||
487 | * Returns: errno | 518 | * Returns: errno |
488 | */ | 519 | */ |
489 | 520 | ||
490 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 521 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
491 | { | 522 | { |
492 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 523 | struct inode *inode = dentry->d_inode; |
524 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | ||
525 | int ret = 0; | ||
493 | 526 | ||
494 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 527 | if (gfs2_is_jdata(GFS2_I(inode))) { |
528 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
529 | return 0; | ||
530 | } | ||
495 | 531 | ||
496 | return 0; | 532 | if (sync_state != 0) { |
533 | if (!datasync) | ||
534 | ret = write_inode_now(inode, 0); | ||
535 | |||
536 | if (gfs2_is_stuffed(GFS2_I(inode))) | ||
537 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
538 | } | ||
539 | |||
540 | return ret; | ||
497 | } | 541 | } |
498 | 542 | ||
499 | /** | 543 | /** |
@@ -515,7 +559,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
515 | 559 | ||
516 | if (!(fl->fl_flags & FL_POSIX)) | 560 | if (!(fl->fl_flags & FL_POSIX)) |
517 | return -ENOLCK; | 561 | return -ENOLCK; |
518 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 562 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
519 | return -ENOLCK; | 563 | return -ENOLCK; |
520 | 564 | ||
521 | if (sdp->sd_args.ar_localflocks) { | 565 | if (sdp->sd_args.ar_localflocks) { |
@@ -544,7 +588,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
544 | { | 588 | { |
545 | struct gfs2_file *fp = file->private_data; | 589 | struct gfs2_file *fp = file->private_data; |
546 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; | 590 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; |
547 | struct gfs2_inode *ip = GFS2_I(file->f_dentry->d_inode); | 591 | struct gfs2_inode *ip = GFS2_I(file->f_path.dentry->d_inode); |
548 | struct gfs2_glock *gl; | 592 | struct gfs2_glock *gl; |
549 | unsigned int state; | 593 | unsigned int state; |
550 | int flags; | 594 | int flags; |
@@ -617,7 +661,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
617 | 661 | ||
618 | if (!(fl->fl_flags & FL_FLOCK)) | 662 | if (!(fl->fl_flags & FL_FLOCK)) |
619 | return -ENOLCK; | 663 | return -ENOLCK; |
620 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 664 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
621 | return -ENOLCK; | 665 | return -ENOLCK; |
622 | 666 | ||
623 | if (sdp->sd_args.ar_localflocks) | 667 | if (sdp->sd_args.ar_localflocks) |
diff --git a/fs/gfs2/ops_file.h b/fs/gfs2/ops_file.h index ce319f89ec8e..7e5d8ec9c846 100644 --- a/fs/gfs2/ops_file.h +++ b/fs/gfs2/ops_file.h | |||
@@ -17,7 +17,7 @@ extern struct file gfs2_internal_file_sentinel; | |||
17 | extern int gfs2_internal_read(struct gfs2_inode *ip, | 17 | extern int gfs2_internal_read(struct gfs2_inode *ip, |
18 | struct file_ra_state *ra_state, | 18 | struct file_ra_state *ra_state, |
19 | char *buf, loff_t *pos, unsigned size); | 19 | char *buf, loff_t *pos, unsigned size); |
20 | 20 | extern void gfs2_set_inode_flags(struct inode *inode); | |
21 | extern const struct file_operations gfs2_file_fops; | 21 | extern const struct file_operations gfs2_file_fops; |
22 | extern const struct file_operations gfs2_dir_fops; | 22 | extern const struct file_operations gfs2_dir_fops; |
23 | 23 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 882873a6bd69..ee80b8a5e7bc 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -237,7 +237,7 @@ fail: | |||
237 | } | 237 | } |
238 | 238 | ||
239 | static struct inode *gfs2_lookup_root(struct super_block *sb, | 239 | static struct inode *gfs2_lookup_root(struct super_block *sb, |
240 | struct gfs2_inum *inum) | 240 | struct gfs2_inum_host *inum) |
241 | { | 241 | { |
242 | return gfs2_inode_lookup(sb, inum, DT_DIR); | 242 | return gfs2_inode_lookup(sb, inum, DT_DIR); |
243 | } | 243 | } |
@@ -246,7 +246,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | |||
246 | { | 246 | { |
247 | struct super_block *sb = sdp->sd_vfs; | 247 | struct super_block *sb = sdp->sd_vfs; |
248 | struct gfs2_holder sb_gh; | 248 | struct gfs2_holder sb_gh; |
249 | struct gfs2_inum *inum; | 249 | struct gfs2_inum_host *inum; |
250 | struct inode *inode; | 250 | struct inode *inode; |
251 | int error = 0; | 251 | int error = 0; |
252 | 252 | ||
@@ -867,9 +867,9 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, | |||
867 | error = -EBUSY; | 867 | error = -EBUSY; |
868 | goto error; | 868 | goto error; |
869 | } | 869 | } |
870 | mutex_lock(&sb->s_bdev->bd_mount_mutex); | 870 | down(&sb->s_bdev->bd_mount_sem); |
871 | new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev); | 871 | new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev); |
872 | mutex_unlock(&sb->s_bdev->bd_mount_mutex); | 872 | up(&sb->s_bdev->bd_mount_sem); |
873 | if (IS_ERR(new)) { | 873 | if (IS_ERR(new)) { |
874 | error = PTR_ERR(new); | 874 | error = PTR_ERR(new); |
875 | goto error; | 875 | goto error; |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index ef6e5ed70e94..636dda4c7d38 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -59,7 +59,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
60 | 60 | ||
61 | for (;;) { | 61 | for (;;) { |
62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode); | 62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); |
63 | if (!IS_ERR(inode)) { | 63 | if (!IS_ERR(inode)) { |
64 | gfs2_trans_end(sdp); | 64 | gfs2_trans_end(sdp); |
65 | if (dip->i_alloc.al_rgd) | 65 | if (dip->i_alloc.al_rgd) |
@@ -144,7 +144,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
144 | int alloc_required; | 144 | int alloc_required; |
145 | int error; | 145 | int error; |
146 | 146 | ||
147 | if (S_ISDIR(ip->i_di.di_mode)) | 147 | if (S_ISDIR(inode->i_mode)) |
148 | return -EPERM; | 148 | return -EPERM; |
149 | 149 | ||
150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
@@ -169,7 +169,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | error = -EINVAL; | 171 | error = -EINVAL; |
172 | if (!dip->i_di.di_nlink) | 172 | if (!dip->i_inode.i_nlink) |
173 | goto out_gunlock; | 173 | goto out_gunlock; |
174 | error = -EFBIG; | 174 | error = -EFBIG; |
175 | if (dip->i_di.di_entries == (u32)-1) | 175 | if (dip->i_di.di_entries == (u32)-1) |
@@ -178,10 +178,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
179 | goto out_gunlock; | 179 | goto out_gunlock; |
180 | error = -EINVAL; | 180 | error = -EINVAL; |
181 | if (!ip->i_di.di_nlink) | 181 | if (!ip->i_inode.i_nlink) |
182 | goto out_gunlock; | 182 | goto out_gunlock; |
183 | error = -EMLINK; | 183 | error = -EMLINK; |
184 | if (ip->i_di.di_nlink == (u32)-1) | 184 | if (ip->i_inode.i_nlink == (u32)-1) |
185 | goto out_gunlock; | 185 | goto out_gunlock; |
186 | 186 | ||
187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | 187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); |
@@ -196,8 +196,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
196 | if (error) | 196 | if (error) |
197 | goto out_alloc; | 197 | goto out_alloc; |
198 | 198 | ||
199 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 199 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
200 | dip->i_di.di_gid); | ||
201 | if (error) | 200 | if (error) |
202 | goto out_gunlock_q; | 201 | goto out_gunlock_q; |
203 | 202 | ||
@@ -220,7 +219,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
220 | } | 219 | } |
221 | 220 | ||
222 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, | 221 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, |
223 | IF2DT(ip->i_di.di_mode)); | 222 | IF2DT(inode->i_mode)); |
224 | if (error) | 223 | if (error) |
225 | goto out_end_trans; | 224 | goto out_end_trans; |
226 | 225 | ||
@@ -326,7 +325,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
326 | 325 | ||
327 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 326 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
328 | 327 | ||
329 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO); | 328 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); |
330 | if (IS_ERR(inode)) { | 329 | if (IS_ERR(inode)) { |
331 | gfs2_holder_uninit(ghs); | 330 | gfs2_holder_uninit(ghs); |
332 | return PTR_ERR(inode); | 331 | return PTR_ERR(inode); |
@@ -339,7 +338,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
339 | error = gfs2_meta_inode_buffer(ip, &dibh); | 338 | error = gfs2_meta_inode_buffer(ip, &dibh); |
340 | 339 | ||
341 | if (!gfs2_assert_withdraw(sdp, !error)) { | 340 | if (!gfs2_assert_withdraw(sdp, !error)) { |
342 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 341 | gfs2_dinode_out(ip, dibh->b_data); |
343 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, | 342 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, |
344 | size); | 343 | size); |
345 | brelse(dibh); | 344 | brelse(dibh); |
@@ -379,7 +378,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
379 | 378 | ||
380 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 379 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
381 | 380 | ||
382 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode); | 381 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); |
383 | if (IS_ERR(inode)) { | 382 | if (IS_ERR(inode)) { |
384 | gfs2_holder_uninit(ghs); | 383 | gfs2_holder_uninit(ghs); |
385 | return PTR_ERR(inode); | 384 | return PTR_ERR(inode); |
@@ -387,10 +386,9 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
387 | 386 | ||
388 | ip = ghs[1].gh_gl->gl_object; | 387 | ip = ghs[1].gh_gl->gl_object; |
389 | 388 | ||
390 | ip->i_di.di_nlink = 2; | 389 | ip->i_inode.i_nlink = 2; |
391 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 390 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
392 | ip->i_di.di_flags |= GFS2_DIF_JDATA; | 391 | ip->i_di.di_flags |= GFS2_DIF_JDATA; |
393 | ip->i_di.di_payload_format = GFS2_FORMAT_DE; | ||
394 | ip->i_di.di_entries = 2; | 392 | ip->i_di.di_entries = 2; |
395 | 393 | ||
396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 394 | error = gfs2_meta_inode_buffer(ip, &dibh); |
@@ -414,7 +412,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
414 | gfs2_inum_out(&dip->i_num, &dent->de_inum); | 412 | gfs2_inum_out(&dip->i_num, &dent->de_inum); |
415 | dent->de_type = cpu_to_be16(DT_DIR); | 413 | dent->de_type = cpu_to_be16(DT_DIR); |
416 | 414 | ||
417 | gfs2_dinode_out(&ip->i_di, di); | 415 | gfs2_dinode_out(ip, di); |
418 | 416 | ||
419 | brelse(dibh); | 417 | brelse(dibh); |
420 | } | 418 | } |
@@ -467,7 +465,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
467 | 465 | ||
468 | if (ip->i_di.di_entries < 2) { | 466 | if (ip->i_di.di_entries < 2) { |
469 | if (gfs2_consist_inode(ip)) | 467 | if (gfs2_consist_inode(ip)) |
470 | gfs2_dinode_print(&ip->i_di); | 468 | gfs2_dinode_print(ip); |
471 | error = -EIO; | 469 | error = -EIO; |
472 | goto out_gunlock; | 470 | goto out_gunlock; |
473 | } | 471 | } |
@@ -504,47 +502,19 @@ out: | |||
504 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | 502 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, |
505 | dev_t dev) | 503 | dev_t dev) |
506 | { | 504 | { |
507 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 505 | struct gfs2_inode *dip = GFS2_I(dir); |
508 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 506 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
509 | struct gfs2_holder ghs[2]; | 507 | struct gfs2_holder ghs[2]; |
510 | struct inode *inode; | 508 | struct inode *inode; |
511 | struct buffer_head *dibh; | ||
512 | u32 major = 0, minor = 0; | ||
513 | int error; | ||
514 | |||
515 | switch (mode & S_IFMT) { | ||
516 | case S_IFBLK: | ||
517 | case S_IFCHR: | ||
518 | major = MAJOR(dev); | ||
519 | minor = MINOR(dev); | ||
520 | break; | ||
521 | case S_IFIFO: | ||
522 | case S_IFSOCK: | ||
523 | break; | ||
524 | default: | ||
525 | return -EOPNOTSUPP; | ||
526 | }; | ||
527 | 509 | ||
528 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 510 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
529 | 511 | ||
530 | inode = gfs2_createi(ghs, &dentry->d_name, mode); | 512 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); |
531 | if (IS_ERR(inode)) { | 513 | if (IS_ERR(inode)) { |
532 | gfs2_holder_uninit(ghs); | 514 | gfs2_holder_uninit(ghs); |
533 | return PTR_ERR(inode); | 515 | return PTR_ERR(inode); |
534 | } | 516 | } |
535 | 517 | ||
536 | ip = ghs[1].gh_gl->gl_object; | ||
537 | |||
538 | ip->i_di.di_major = major; | ||
539 | ip->i_di.di_minor = minor; | ||
540 | |||
541 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
542 | |||
543 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
544 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | ||
545 | brelse(dibh); | ||
546 | } | ||
547 | |||
548 | gfs2_trans_end(sdp); | 518 | gfs2_trans_end(sdp); |
549 | if (dip->i_alloc.al_rgd) | 519 | if (dip->i_alloc.al_rgd) |
550 | gfs2_inplace_release(dip); | 520 | gfs2_inplace_release(dip); |
@@ -592,11 +562,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
592 | 562 | ||
593 | /* Make sure we aren't trying to move a dirctory into it's subdir */ | 563 | /* Make sure we aren't trying to move a dirctory into it's subdir */ |
594 | 564 | ||
595 | if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) { | 565 | if (S_ISDIR(ip->i_inode.i_mode) && odip != ndip) { |
596 | dir_rename = 1; | 566 | dir_rename = 1; |
597 | 567 | ||
598 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, | 568 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, |
599 | LM_ST_EXCLUSIVE, 0, | ||
600 | &r_gh); | 569 | &r_gh); |
601 | if (error) | 570 | if (error) |
602 | goto out; | 571 | goto out; |
@@ -637,10 +606,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
637 | if (error) | 606 | if (error) |
638 | goto out_gunlock; | 607 | goto out_gunlock; |
639 | 608 | ||
640 | if (S_ISDIR(nip->i_di.di_mode)) { | 609 | if (S_ISDIR(nip->i_inode.i_mode)) { |
641 | if (nip->i_di.di_entries < 2) { | 610 | if (nip->i_di.di_entries < 2) { |
642 | if (gfs2_consist_inode(nip)) | 611 | if (gfs2_consist_inode(nip)) |
643 | gfs2_dinode_print(&nip->i_di); | 612 | gfs2_dinode_print(nip); |
644 | error = -EIO; | 613 | error = -EIO; |
645 | goto out_gunlock; | 614 | goto out_gunlock; |
646 | } | 615 | } |
@@ -666,7 +635,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
666 | }; | 635 | }; |
667 | 636 | ||
668 | if (odip != ndip) { | 637 | if (odip != ndip) { |
669 | if (!ndip->i_di.di_nlink) { | 638 | if (!ndip->i_inode.i_nlink) { |
670 | error = -EINVAL; | 639 | error = -EINVAL; |
671 | goto out_gunlock; | 640 | goto out_gunlock; |
672 | } | 641 | } |
@@ -674,8 +643,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
674 | error = -EFBIG; | 643 | error = -EFBIG; |
675 | goto out_gunlock; | 644 | goto out_gunlock; |
676 | } | 645 | } |
677 | if (S_ISDIR(ip->i_di.di_mode) && | 646 | if (S_ISDIR(ip->i_inode.i_mode) && |
678 | ndip->i_di.di_nlink == (u32)-1) { | 647 | ndip->i_inode.i_nlink == (u32)-1) { |
679 | error = -EMLINK; | 648 | error = -EMLINK; |
680 | goto out_gunlock; | 649 | goto out_gunlock; |
681 | } | 650 | } |
@@ -702,8 +671,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
702 | if (error) | 671 | if (error) |
703 | goto out_alloc; | 672 | goto out_alloc; |
704 | 673 | ||
705 | error = gfs2_quota_check(ndip, ndip->i_di.di_uid, | 674 | error = gfs2_quota_check(ndip, ndip->i_inode.i_uid, ndip->i_inode.i_gid); |
706 | ndip->i_di.di_gid); | ||
707 | if (error) | 675 | if (error) |
708 | goto out_gunlock_q; | 676 | goto out_gunlock_q; |
709 | 677 | ||
@@ -729,7 +697,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
729 | /* Remove the target file, if it exists */ | 697 | /* Remove the target file, if it exists */ |
730 | 698 | ||
731 | if (nip) { | 699 | if (nip) { |
732 | if (S_ISDIR(nip->i_di.di_mode)) | 700 | if (S_ISDIR(nip->i_inode.i_mode)) |
733 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); | 701 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); |
734 | else { | 702 | else { |
735 | error = gfs2_dir_del(ndip, &ndentry->d_name); | 703 | error = gfs2_dir_del(ndip, &ndentry->d_name); |
@@ -760,9 +728,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
760 | error = gfs2_meta_inode_buffer(ip, &dibh); | 728 | error = gfs2_meta_inode_buffer(ip, &dibh); |
761 | if (error) | 729 | if (error) |
762 | goto out_end_trans; | 730 | goto out_end_trans; |
763 | ip->i_di.di_ctime = get_seconds(); | 731 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
764 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 732 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
765 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 733 | gfs2_dinode_out(ip, dibh->b_data); |
766 | brelse(dibh); | 734 | brelse(dibh); |
767 | } | 735 | } |
768 | 736 | ||
@@ -771,7 +739,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
771 | goto out_end_trans; | 739 | goto out_end_trans; |
772 | 740 | ||
773 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, | 741 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, |
774 | IF2DT(ip->i_di.di_mode)); | 742 | IF2DT(ip->i_inode.i_mode)); |
775 | if (error) | 743 | if (error) |
776 | goto out_end_trans; | 744 | goto out_end_trans; |
777 | 745 | ||
@@ -867,6 +835,10 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
867 | * @mask: | 835 | * @mask: |
868 | * @nd: passed from Linux VFS, ignored by us | 836 | * @nd: passed from Linux VFS, ignored by us |
869 | * | 837 | * |
838 | * This may be called from the VFS directly, or from within GFS2 with the | ||
839 | * inode locked, so we look to see if the glock is already locked and only | ||
840 | * lock the glock if its not already been done. | ||
841 | * | ||
870 | * Returns: errno | 842 | * Returns: errno |
871 | */ | 843 | */ |
872 | 844 | ||
@@ -875,15 +847,18 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
875 | struct gfs2_inode *ip = GFS2_I(inode); | 847 | struct gfs2_inode *ip = GFS2_I(inode); |
876 | struct gfs2_holder i_gh; | 848 | struct gfs2_holder i_gh; |
877 | int error; | 849 | int error; |
850 | int unlock = 0; | ||
878 | 851 | ||
879 | if (ip->i_vn == ip->i_gl->gl_vn) | 852 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
880 | return generic_permission(inode, mask, gfs2_check_acl); | 853 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); |
854 | if (error) | ||
855 | return error; | ||
856 | unlock = 1; | ||
857 | } | ||
881 | 858 | ||
882 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 859 | error = generic_permission(inode, mask, gfs2_check_acl); |
883 | if (!error) { | 860 | if (unlock) |
884 | error = generic_permission(inode, mask, gfs2_check_acl_locked); | ||
885 | gfs2_glock_dq_uninit(&i_gh); | 861 | gfs2_glock_dq_uninit(&i_gh); |
886 | } | ||
887 | 862 | ||
888 | return error; | 863 | return error; |
889 | } | 864 | } |
@@ -914,8 +889,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
914 | u32 ouid, ogid, nuid, ngid; | 889 | u32 ouid, ogid, nuid, ngid; |
915 | int error; | 890 | int error; |
916 | 891 | ||
917 | ouid = ip->i_di.di_uid; | 892 | ouid = inode->i_uid; |
918 | ogid = ip->i_di.di_gid; | 893 | ogid = inode->i_gid; |
919 | nuid = attr->ia_uid; | 894 | nuid = attr->ia_uid; |
920 | ngid = attr->ia_gid; | 895 | ngid = attr->ia_gid; |
921 | 896 | ||
@@ -946,10 +921,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
946 | 921 | ||
947 | error = inode_setattr(inode, attr); | 922 | error = inode_setattr(inode, attr); |
948 | gfs2_assert_warn(sdp, !error); | 923 | gfs2_assert_warn(sdp, !error); |
949 | gfs2_inode_attr_out(ip); | ||
950 | 924 | ||
951 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 925 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
952 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 926 | gfs2_dinode_out(ip, dibh->b_data); |
953 | brelse(dibh); | 927 | brelse(dibh); |
954 | 928 | ||
955 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 929 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
@@ -1018,6 +992,12 @@ out: | |||
1018 | * @dentry: The dentry to stat | 992 | * @dentry: The dentry to stat |
1019 | * @stat: The inode's stats | 993 | * @stat: The inode's stats |
1020 | * | 994 | * |
995 | * This may be called from the VFS directly, or from within GFS2 with the | ||
996 | * inode locked, so we look to see if the glock is already locked and only | ||
997 | * lock the glock if its not already been done. Note that its the NFS | ||
998 | * readdirplus operation which causes this to be called (from filldir) | ||
999 | * with the glock already held. | ||
1000 | * | ||
1021 | * Returns: errno | 1001 | * Returns: errno |
1022 | */ | 1002 | */ |
1023 | 1003 | ||
@@ -1028,14 +1008,20 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1028 | struct gfs2_inode *ip = GFS2_I(inode); | 1008 | struct gfs2_inode *ip = GFS2_I(inode); |
1029 | struct gfs2_holder gh; | 1009 | struct gfs2_holder gh; |
1030 | int error; | 1010 | int error; |
1011 | int unlock = 0; | ||
1031 | 1012 | ||
1032 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1013 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
1033 | if (!error) { | 1014 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
1034 | generic_fillattr(inode, stat); | 1015 | if (error) |
1035 | gfs2_glock_dq_uninit(&gh); | 1016 | return error; |
1017 | unlock = 1; | ||
1036 | } | 1018 | } |
1037 | 1019 | ||
1038 | return error; | 1020 | generic_fillattr(inode, stat); |
1021 | if (unlock); | ||
1022 | gfs2_glock_dq_uninit(&gh); | ||
1023 | |||
1024 | return 0; | ||
1039 | } | 1025 | } |
1040 | 1026 | ||
1041 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | 1027 | static int gfs2_setxattr(struct dentry *dentry, const char *name, |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index b47d9598c047..7685b46f934b 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -157,7 +157,8 @@ static void gfs2_write_super(struct super_block *sb) | |||
157 | static int gfs2_sync_fs(struct super_block *sb, int wait) | 157 | static int gfs2_sync_fs(struct super_block *sb, int wait) |
158 | { | 158 | { |
159 | sb->s_dirt = 0; | 159 | sb->s_dirt = 0; |
160 | gfs2_log_flush(sb->s_fs_info, NULL); | 160 | if (wait) |
161 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
161 | return 0; | 162 | return 0; |
162 | } | 163 | } |
163 | 164 | ||
@@ -215,7 +216,7 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
215 | { | 216 | { |
216 | struct super_block *sb = dentry->d_inode->i_sb; | 217 | struct super_block *sb = dentry->d_inode->i_sb; |
217 | struct gfs2_sbd *sdp = sb->s_fs_info; | 218 | struct gfs2_sbd *sdp = sb->s_fs_info; |
218 | struct gfs2_statfs_change sc; | 219 | struct gfs2_statfs_change_host sc; |
219 | int error; | 220 | int error; |
220 | 221 | ||
221 | if (gfs2_tune_get(sdp, gt_statfs_slow)) | 222 | if (gfs2_tune_get(sdp, gt_statfs_slow)) |
@@ -293,8 +294,6 @@ static void gfs2_clear_inode(struct inode *inode) | |||
293 | */ | 294 | */ |
294 | if (inode->i_private) { | 295 | if (inode->i_private) { |
295 | struct gfs2_inode *ip = GFS2_I(inode); | 296 | struct gfs2_inode *ip = GFS2_I(inode); |
296 | gfs2_glock_inode_squish(inode); | ||
297 | gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED); | ||
298 | ip->i_gl->gl_object = NULL; | 297 | ip->i_gl->gl_object = NULL; |
299 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | 298 | gfs2_glock_schedule_for_reclaim(ip->i_gl); |
300 | gfs2_glock_put(ip->i_gl); | 299 | gfs2_glock_put(ip->i_gl); |
@@ -395,7 +394,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
395 | if (!inode->i_private) | 394 | if (!inode->i_private) |
396 | goto out; | 395 | goto out; |
397 | 396 | ||
398 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh); | 397 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); |
399 | if (unlikely(error)) { | 398 | if (unlikely(error)) { |
400 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 399 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
401 | goto out; | 400 | goto out; |
@@ -407,7 +406,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
407 | if (error) | 406 | if (error) |
408 | goto out_uninit; | 407 | goto out_uninit; |
409 | 408 | ||
410 | if (S_ISDIR(ip->i_di.di_mode) && | 409 | if (S_ISDIR(inode->i_mode) && |
411 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { | 410 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { |
412 | error = gfs2_dir_exhash_dealloc(ip); | 411 | error = gfs2_dir_exhash_dealloc(ip); |
413 | if (error) | 412 | if (error) |
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index 5453d2947ab3..45a5f11fc39a 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
@@ -76,7 +76,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
76 | if (error) | 76 | if (error) |
77 | goto out; | 77 | goto out; |
78 | 78 | ||
79 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 79 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
80 | if (error) | 80 | if (error) |
81 | goto out_gunlock_q; | 81 | goto out_gunlock_q; |
82 | 82 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index a3deae7416c9..d0db881b55d2 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -452,19 +452,19 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
453 | return 0; | 453 | return 0; |
454 | 454 | ||
455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_di.di_uid, CREATE, qd); | 455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd); |
456 | if (error) | 456 | if (error) |
457 | goto out; | 457 | goto out; |
458 | al->al_qd_num++; | 458 | al->al_qd_num++; |
459 | qd++; | 459 | qd++; |
460 | 460 | ||
461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_di.di_gid, CREATE, qd); | 461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd); |
462 | if (error) | 462 | if (error) |
463 | goto out; | 463 | goto out; |
464 | al->al_qd_num++; | 464 | al->al_qd_num++; |
465 | qd++; | 465 | qd++; |
466 | 466 | ||
467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_di.di_uid) { | 467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { |
468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); | 468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); |
469 | if (error) | 469 | if (error) |
470 | goto out; | 470 | goto out; |
@@ -472,7 +472,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
472 | qd++; | 472 | qd++; |
473 | } | 473 | } |
474 | 474 | ||
475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_di.di_gid) { | 475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) { |
476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); | 476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); |
477 | if (error) | 477 | if (error) |
478 | goto out; | 478 | goto out; |
@@ -539,8 +539,7 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
539 | qc->qc_id = cpu_to_be32(qd->qd_id); | 539 | qc->qc_id = cpu_to_be32(qd->qd_id); |
540 | } | 540 | } |
541 | 541 | ||
542 | x = qc->qc_change; | 542 | x = be64_to_cpu(qc->qc_change) + change; |
543 | x = be64_to_cpu(x) + change; | ||
544 | qc->qc_change = cpu_to_be64(x); | 543 | qc->qc_change = cpu_to_be64(x); |
545 | 544 | ||
546 | spin_lock(&sdp->sd_quota_spin); | 545 | spin_lock(&sdp->sd_quota_spin); |
@@ -743,7 +742,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh, | |||
743 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; | 742 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; |
744 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); | 743 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); |
745 | struct gfs2_holder i_gh; | 744 | struct gfs2_holder i_gh; |
746 | struct gfs2_quota q; | 745 | struct gfs2_quota_host q; |
747 | char buf[sizeof(struct gfs2_quota)]; | 746 | char buf[sizeof(struct gfs2_quota)]; |
748 | struct file_ra_state ra_state; | 747 | struct file_ra_state ra_state; |
749 | int error; | 748 | int error; |
@@ -1103,7 +1102,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | |||
1103 | 1102 | ||
1104 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; | 1103 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; |
1105 | y++, slot++) { | 1104 | y++, slot++) { |
1106 | struct gfs2_quota_change qc; | 1105 | struct gfs2_quota_change_host qc; |
1107 | struct gfs2_quota_data *qd; | 1106 | struct gfs2_quota_data *qd; |
1108 | 1107 | ||
1109 | gfs2_quota_change_in(&qc, bh->b_data + | 1108 | gfs2_quota_change_in(&qc, bh->b_data + |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 62cd223819b7..d0c806b85c86 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -132,10 +132,11 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp) | |||
132 | */ | 132 | */ |
133 | 133 | ||
134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | 134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, |
135 | struct gfs2_log_header *head) | 135 | struct gfs2_log_header_host *head) |
136 | { | 136 | { |
137 | struct buffer_head *bh; | 137 | struct buffer_head *bh; |
138 | struct gfs2_log_header lh; | 138 | struct gfs2_log_header_host lh; |
139 | const u32 nothing = 0; | ||
139 | u32 hash; | 140 | u32 hash; |
140 | int error; | 141 | int error; |
141 | 142 | ||
@@ -143,11 +144,11 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
143 | if (error) | 144 | if (error) |
144 | return error; | 145 | return error; |
145 | 146 | ||
146 | memcpy(&lh, bh->b_data, sizeof(struct gfs2_log_header)); | 147 | hash = crc32_le((u32)~0, bh->b_data, sizeof(struct gfs2_log_header) - |
147 | lh.lh_hash = 0; | 148 | sizeof(u32)); |
148 | hash = gfs2_disk_hash((char *)&lh, sizeof(struct gfs2_log_header)); | 149 | hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); |
150 | hash ^= (u32)~0; | ||
149 | gfs2_log_header_in(&lh, bh->b_data); | 151 | gfs2_log_header_in(&lh, bh->b_data); |
150 | |||
151 | brelse(bh); | 152 | brelse(bh); |
152 | 153 | ||
153 | if (lh.lh_header.mh_magic != GFS2_MAGIC || | 154 | if (lh.lh_header.mh_magic != GFS2_MAGIC || |
@@ -174,7 +175,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
174 | */ | 175 | */ |
175 | 176 | ||
176 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | 177 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, |
177 | struct gfs2_log_header *head) | 178 | struct gfs2_log_header_host *head) |
178 | { | 179 | { |
179 | unsigned int orig_blk = *blk; | 180 | unsigned int orig_blk = *blk; |
180 | int error; | 181 | int error; |
@@ -205,10 +206,10 @@ static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | |||
205 | * Returns: errno | 206 | * Returns: errno |
206 | */ | 207 | */ |
207 | 208 | ||
208 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 209 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
209 | { | 210 | { |
210 | unsigned int blk = head->lh_blkno; | 211 | unsigned int blk = head->lh_blkno; |
211 | struct gfs2_log_header lh; | 212 | struct gfs2_log_header_host lh; |
212 | int error; | 213 | int error; |
213 | 214 | ||
214 | for (;;) { | 215 | for (;;) { |
@@ -245,9 +246,9 @@ static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | |||
245 | * Returns: errno | 246 | * Returns: errno |
246 | */ | 247 | */ |
247 | 248 | ||
248 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 249 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
249 | { | 250 | { |
250 | struct gfs2_log_header lh_1, lh_m; | 251 | struct gfs2_log_header_host lh_1, lh_m; |
251 | u32 blk_1, blk_2, blk_m; | 252 | u32 blk_1, blk_2, blk_m; |
252 | int error; | 253 | int error; |
253 | 254 | ||
@@ -320,7 +321,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
320 | length = be32_to_cpu(ld->ld_length); | 321 | length = be32_to_cpu(ld->ld_length); |
321 | 322 | ||
322 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { | 323 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { |
323 | struct gfs2_log_header lh; | 324 | struct gfs2_log_header_host lh; |
324 | error = get_log_header(jd, start, &lh); | 325 | error = get_log_header(jd, start, &lh); |
325 | if (!error) { | 326 | if (!error) { |
326 | gfs2_replay_incr_blk(sdp, &start); | 327 | gfs2_replay_incr_blk(sdp, &start); |
@@ -363,7 +364,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
363 | * Returns: errno | 364 | * Returns: errno |
364 | */ | 365 | */ |
365 | 366 | ||
366 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 367 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
367 | { | 368 | { |
368 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 369 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
369 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 370 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
@@ -425,7 +426,7 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) | |||
425 | { | 426 | { |
426 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 427 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
427 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 428 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
428 | struct gfs2_log_header head; | 429 | struct gfs2_log_header_host head; |
429 | struct gfs2_holder j_gh, ji_gh, t_gh; | 430 | struct gfs2_holder j_gh, ji_gh, t_gh; |
430 | unsigned long t; | 431 | unsigned long t; |
431 | int ro = 0; | 432 | int ro = 0; |
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index 961feedf4d8b..f7235e61c723 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -26,7 +26,7 @@ int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); | |||
26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); | 26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); |
27 | 27 | ||
28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, | 28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, |
29 | struct gfs2_log_header *head); | 29 | struct gfs2_log_header_host *head); |
30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
31 | void gfs2_check_journals(struct gfs2_sbd *sdp); | 31 | void gfs2_check_journals(struct gfs2_sbd *sdp); |
32 | 32 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index b261385c0065..ff0846528d54 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -253,7 +253,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
253 | 253 | ||
254 | } | 254 | } |
255 | 255 | ||
256 | static inline int rgrp_contains_block(struct gfs2_rindex *ri, u64 block) | 256 | static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) |
257 | { | 257 | { |
258 | u64 first = ri->ri_data0; | 258 | u64 first = ri->ri_data0; |
259 | u64 last = first + ri->ri_data; | 259 | u64 last = first + ri->ri_data; |
@@ -1217,7 +1217,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
1217 | al->al_alloced++; | 1217 | al->al_alloced++; |
1218 | 1218 | ||
1219 | gfs2_statfs_change(sdp, 0, -1, 0); | 1219 | gfs2_statfs_change(sdp, 0, -1, 0); |
1220 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1220 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1221 | 1221 | ||
1222 | spin_lock(&sdp->sd_rindex_spin); | 1222 | spin_lock(&sdp->sd_rindex_spin); |
1223 | rgd->rd_free_clone--; | 1223 | rgd->rd_free_clone--; |
@@ -1261,7 +1261,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) | |||
1261 | al->al_alloced++; | 1261 | al->al_alloced++; |
1262 | 1262 | ||
1263 | gfs2_statfs_change(sdp, 0, -1, 0); | 1263 | gfs2_statfs_change(sdp, 0, -1, 0); |
1264 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1264 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1265 | gfs2_trans_add_unrevoke(sdp, block); | 1265 | gfs2_trans_add_unrevoke(sdp, block); |
1266 | 1266 | ||
1267 | spin_lock(&sdp->sd_rindex_spin); | 1267 | spin_lock(&sdp->sd_rindex_spin); |
@@ -1337,8 +1337,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1337 | gfs2_trans_add_rg(rgd); | 1337 | gfs2_trans_add_rg(rgd); |
1338 | 1338 | ||
1339 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1339 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1340 | gfs2_quota_change(ip, -(s64)blen, | 1340 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1341 | ip->i_di.di_uid, ip->i_di.di_gid); | ||
1342 | } | 1341 | } |
1343 | 1342 | ||
1344 | /** | 1343 | /** |
@@ -1366,7 +1365,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1366 | gfs2_trans_add_rg(rgd); | 1365 | gfs2_trans_add_rg(rgd); |
1367 | 1366 | ||
1368 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1367 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1369 | gfs2_quota_change(ip, -(s64)blen, ip->i_di.di_uid, ip->i_di.di_gid); | 1368 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1370 | gfs2_meta_wipe(ip, bstart, blen); | 1369 | gfs2_meta_wipe(ip, bstart, blen); |
1371 | } | 1370 | } |
1372 | 1371 | ||
@@ -1411,7 +1410,7 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1411 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | 1410 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1412 | { | 1411 | { |
1413 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); | 1412 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); |
1414 | gfs2_quota_change(ip, -1, ip->i_di.di_uid, ip->i_di.di_gid); | 1413 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1415 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); | 1414 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); |
1416 | } | 1415 | } |
1417 | 1416 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 6a78b1b32e25..43a24f2e5905 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -97,7 +97,7 @@ void gfs2_tune_init(struct gfs2_tune *gt) | |||
97 | * changed. | 97 | * changed. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) | 100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) |
101 | { | 101 | { |
102 | unsigned int x; | 102 | unsigned int x; |
103 | 103 | ||
@@ -180,6 +180,24 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | /** | ||
184 | * gfs2_read_super - Read the gfs2 super block from disk | ||
185 | * @sb: The VFS super block | ||
186 | * @sector: The location of the super block | ||
187 | * | ||
188 | * This uses the bio functions to read the super block from disk | ||
189 | * because we want to be 100% sure that we never read cached data. | ||
190 | * A super block is read twice only during each GFS2 mount and is | ||
191 | * never written to by the filesystem. The first time its read no | ||
192 | * locks are held, and the only details which are looked at are those | ||
193 | * relating to the locking protocol. Once locking is up and working, | ||
194 | * the sb is read again under the lock to establish the location of | ||
195 | * the master directory (contains pointers to journals etc) and the | ||
196 | * root directory. | ||
197 | * | ||
198 | * Returns: A page containing the sb or NULL | ||
199 | */ | ||
200 | |||
183 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | 201 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) |
184 | { | 202 | { |
185 | struct page *page; | 203 | struct page *page; |
@@ -199,7 +217,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
199 | return NULL; | 217 | return NULL; |
200 | } | 218 | } |
201 | 219 | ||
202 | bio->bi_sector = sector; | 220 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
203 | bio->bi_bdev = sb->s_bdev; | 221 | bio->bi_bdev = sb->s_bdev; |
204 | bio_add_page(bio, page, PAGE_SIZE, 0); | 222 | bio_add_page(bio, page, PAGE_SIZE, 0); |
205 | 223 | ||
@@ -508,7 +526,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
508 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 526 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
509 | struct gfs2_glock *j_gl = ip->i_gl; | 527 | struct gfs2_glock *j_gl = ip->i_gl; |
510 | struct gfs2_holder t_gh; | 528 | struct gfs2_holder t_gh; |
511 | struct gfs2_log_header head; | 529 | struct gfs2_log_header_host head; |
512 | int error; | 530 | int error; |
513 | 531 | ||
514 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, | 532 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, |
@@ -517,7 +535,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
517 | return error; | 535 | return error; |
518 | 536 | ||
519 | gfs2_meta_cache_flush(ip); | 537 | gfs2_meta_cache_flush(ip); |
520 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 538 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
521 | 539 | ||
522 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 540 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
523 | if (error) | 541 | if (error) |
@@ -587,9 +605,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
587 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 605 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
588 | { | 606 | { |
589 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 607 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
590 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 608 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
591 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 609 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
592 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 610 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
593 | struct buffer_head *m_bh, *l_bh; | 611 | struct buffer_head *m_bh, *l_bh; |
594 | struct gfs2_holder gh; | 612 | struct gfs2_holder gh; |
595 | int error; | 613 | int error; |
@@ -634,7 +652,7 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
634 | s64 dinodes) | 652 | s64 dinodes) |
635 | { | 653 | { |
636 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 654 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
637 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 655 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
638 | struct buffer_head *l_bh; | 656 | struct buffer_head *l_bh; |
639 | int error; | 657 | int error; |
640 | 658 | ||
@@ -660,8 +678,8 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) | |||
660 | { | 678 | { |
661 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 679 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
662 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 680 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
663 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 681 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
664 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 682 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
665 | struct gfs2_holder gh; | 683 | struct gfs2_holder gh; |
666 | struct buffer_head *m_bh, *l_bh; | 684 | struct buffer_head *m_bh, *l_bh; |
667 | int error; | 685 | int error; |
@@ -727,10 +745,10 @@ out: | |||
727 | * Returns: errno | 745 | * Returns: errno |
728 | */ | 746 | */ |
729 | 747 | ||
730 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 748 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
731 | { | 749 | { |
732 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 750 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
733 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 751 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
734 | 752 | ||
735 | spin_lock(&sdp->sd_statfs_spin); | 753 | spin_lock(&sdp->sd_statfs_spin); |
736 | 754 | ||
@@ -760,7 +778,7 @@ int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
760 | */ | 778 | */ |
761 | 779 | ||
762 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | 780 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, |
763 | struct gfs2_statfs_change *sc) | 781 | struct gfs2_statfs_change_host *sc) |
764 | { | 782 | { |
765 | gfs2_rgrp_verify(rgd); | 783 | gfs2_rgrp_verify(rgd); |
766 | sc->sc_total += rgd->rd_ri.ri_data; | 784 | sc->sc_total += rgd->rd_ri.ri_data; |
@@ -782,7 +800,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | |||
782 | * Returns: errno | 800 | * Returns: errno |
783 | */ | 801 | */ |
784 | 802 | ||
785 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 803 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
786 | { | 804 | { |
787 | struct gfs2_holder ri_gh; | 805 | struct gfs2_holder ri_gh; |
788 | struct gfs2_rgrpd *rgd_next; | 806 | struct gfs2_rgrpd *rgd_next; |
@@ -792,7 +810,7 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
792 | int done; | 810 | int done; |
793 | int error = 0, err; | 811 | int error = 0, err; |
794 | 812 | ||
795 | memset(sc, 0, sizeof(struct gfs2_statfs_change)); | 813 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); |
796 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | 814 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); |
797 | if (!gha) | 815 | if (!gha) |
798 | return -ENOMEM; | 816 | return -ENOMEM; |
@@ -873,7 +891,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
873 | struct gfs2_jdesc *jd; | 891 | struct gfs2_jdesc *jd; |
874 | struct lfcc *lfcc; | 892 | struct lfcc *lfcc; |
875 | LIST_HEAD(list); | 893 | LIST_HEAD(list); |
876 | struct gfs2_log_header lh; | 894 | struct gfs2_log_header_host lh; |
877 | int error; | 895 | int error; |
878 | 896 | ||
879 | error = gfs2_jindex_hold(sdp, &ji_gh); | 897 | error = gfs2_jindex_hold(sdp, &ji_gh); |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 5bb443ae0f59..e590b2df11dc 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | void gfs2_tune_init(struct gfs2_tune *gt); | 15 | void gfs2_tune_init(struct gfs2_tune *gt); |
16 | 16 | ||
17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent); | 17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); |
18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); | 18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); |
19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); | 19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); |
20 | 20 | ||
@@ -45,8 +45,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp); | |||
45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, | 45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, |
46 | s64 total, s64 free, s64 dinodes); | 46 | s64 total, s64 free, s64 dinodes); |
47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); | 47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); |
48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
50 | 50 | ||
51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); | 51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); |
52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); | 52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 0e0ec988f731..983eaf1e06be 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -426,9 +426,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
426 | } \ | 426 | } \ |
427 | TUNE_ATTR_2(name, name##_store) | 427 | TUNE_ATTR_2(name, name##_store) |
428 | 428 | ||
429 | TUNE_ATTR(ilimit, 0); | ||
430 | TUNE_ATTR(ilimit_tries, 0); | ||
431 | TUNE_ATTR(ilimit_min, 0); | ||
432 | TUNE_ATTR(demote_secs, 0); | 429 | TUNE_ATTR(demote_secs, 0); |
433 | TUNE_ATTR(incore_log_blocks, 0); | 430 | TUNE_ATTR(incore_log_blocks, 0); |
434 | TUNE_ATTR(log_flush_secs, 0); | 431 | TUNE_ATTR(log_flush_secs, 0); |
@@ -447,7 +444,6 @@ TUNE_ATTR(quota_simul_sync, 1); | |||
447 | TUNE_ATTR(quota_cache_secs, 1); | 444 | TUNE_ATTR(quota_cache_secs, 1); |
448 | TUNE_ATTR(max_atomic_write, 1); | 445 | TUNE_ATTR(max_atomic_write, 1); |
449 | TUNE_ATTR(stall_secs, 1); | 446 | TUNE_ATTR(stall_secs, 1); |
450 | TUNE_ATTR(entries_per_readdir, 1); | ||
451 | TUNE_ATTR(greedy_default, 1); | 447 | TUNE_ATTR(greedy_default, 1); |
452 | TUNE_ATTR(greedy_quantum, 1); | 448 | TUNE_ATTR(greedy_quantum, 1); |
453 | TUNE_ATTR(greedy_max, 1); | 449 | TUNE_ATTR(greedy_max, 1); |
@@ -459,9 +455,6 @@ TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | |||
459 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 455 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
460 | 456 | ||
461 | static struct attribute *tune_attrs[] = { | 457 | static struct attribute *tune_attrs[] = { |
462 | &tune_attr_ilimit.attr, | ||
463 | &tune_attr_ilimit_tries.attr, | ||
464 | &tune_attr_ilimit_min.attr, | ||
465 | &tune_attr_demote_secs.attr, | 458 | &tune_attr_demote_secs.attr, |
466 | &tune_attr_incore_log_blocks.attr, | 459 | &tune_attr_incore_log_blocks.attr, |
467 | &tune_attr_log_flush_secs.attr, | 460 | &tune_attr_log_flush_secs.attr, |
@@ -478,7 +471,6 @@ static struct attribute *tune_attrs[] = { | |||
478 | &tune_attr_quota_cache_secs.attr, | 471 | &tune_attr_quota_cache_secs.attr, |
479 | &tune_attr_max_atomic_write.attr, | 472 | &tune_attr_max_atomic_write.attr, |
480 | &tune_attr_stall_secs.attr, | 473 | &tune_attr_stall_secs.attr, |
481 | &tune_attr_entries_per_readdir.attr, | ||
482 | &tune_attr_greedy_default.attr, | 474 | &tune_attr_greedy_default.attr, |
483 | &tune_attr_greedy_quantum.attr, | 475 | &tune_attr_greedy_quantum.attr, |
484 | &tune_attr_greedy_max.attr, | 476 | &tune_attr_greedy_max.attr, |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 196c604faadc..e5707a9f78c2 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -23,9 +23,9 @@ | |||
23 | #include "lm.h" | 23 | #include "lm.h" |
24 | #include "util.h" | 24 | #include "util.h" |
25 | 25 | ||
26 | kmem_cache_t *gfs2_glock_cachep __read_mostly; | 26 | struct kmem_cache *gfs2_glock_cachep __read_mostly; |
27 | kmem_cache_t *gfs2_inode_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_inode_cachep __read_mostly; |
28 | kmem_cache_t *gfs2_bufdata_cachep __read_mostly; | 28 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
29 | 29 | ||
30 | void gfs2_assert_i(struct gfs2_sbd *sdp) | 30 | void gfs2_assert_i(struct gfs2_sbd *sdp) |
31 | { | 31 | { |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 76a50899fe9e..28938a46cf47 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -83,8 +83,7 @@ static inline int gfs2_meta_check_i(struct gfs2_sbd *sdp, | |||
83 | char *file, unsigned int line) | 83 | char *file, unsigned int line) |
84 | { | 84 | { |
85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
86 | u32 magic = mh->mh_magic; | 86 | u32 magic = be32_to_cpu(mh->mh_magic); |
87 | magic = be32_to_cpu(magic); | ||
88 | if (unlikely(magic != GFS2_MAGIC)) | 87 | if (unlikely(magic != GFS2_MAGIC)) |
89 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 88 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
90 | file, line); | 89 | file, line); |
@@ -107,9 +106,8 @@ static inline int gfs2_metatype_check_i(struct gfs2_sbd *sdp, | |||
107 | char *file, unsigned int line) | 106 | char *file, unsigned int line) |
108 | { | 107 | { |
109 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 108 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
110 | u32 magic = mh->mh_magic; | 109 | u32 magic = be32_to_cpu(mh->mh_magic); |
111 | u16 t = be32_to_cpu(mh->mh_type); | 110 | u16 t = be32_to_cpu(mh->mh_type); |
112 | magic = be32_to_cpu(magic); | ||
113 | if (unlikely(magic != GFS2_MAGIC)) | 111 | if (unlikely(magic != GFS2_MAGIC)) |
114 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 112 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
115 | file, line); | 113 | file, line); |
@@ -146,9 +144,9 @@ int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
146 | gfs2_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); | 144 | gfs2_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); |
147 | 145 | ||
148 | 146 | ||
149 | extern kmem_cache_t *gfs2_glock_cachep; | 147 | extern struct kmem_cache *gfs2_glock_cachep; |
150 | extern kmem_cache_t *gfs2_inode_cachep; | 148 | extern struct kmem_cache *gfs2_inode_cachep; |
151 | extern kmem_cache_t *gfs2_bufdata_cachep; | 149 | extern struct kmem_cache *gfs2_bufdata_cachep; |
152 | 150 | ||
153 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, | 151 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, |
154 | unsigned int *p) | 152 | unsigned int *p) |
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 37d681b4f216..e2e0358da335 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -53,7 +53,7 @@ done: | |||
53 | */ | 53 | */ |
54 | static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 54 | static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
55 | { | 55 | { |
56 | struct inode *inode = filp->f_dentry->d_inode; | 56 | struct inode *inode = filp->f_path.dentry->d_inode; |
57 | struct super_block *sb = inode->i_sb; | 57 | struct super_block *sb = inode->i_sb; |
58 | int len, err; | 58 | int len, err; |
59 | char strbuf[HFS_MAX_NAMELEN]; | 59 | char strbuf[HFS_MAX_NAMELEN]; |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 02f5573e0349..5cb7f8fee8d6 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -102,7 +102,7 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb, | |||
102 | const struct iovec *iov, loff_t offset, unsigned long nr_segs) | 102 | const struct iovec *iov, loff_t offset, unsigned long nr_segs) |
103 | { | 103 | { |
104 | struct file *file = iocb->ki_filp; | 104 | struct file *file = iocb->ki_filp; |
105 | struct inode *inode = file->f_dentry->d_inode->i_mapping->host; | 105 | struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; |
106 | 106 | ||
107 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 107 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
108 | offset, nr_segs, hfs_get_block, NULL); | 108 | offset, nr_segs, hfs_get_block, NULL); |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 85b17b3fa4a0..a36987966004 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "hfs_fs.h" | 24 | #include "hfs_fs.h" |
25 | #include "btree.h" | 25 | #include "btree.h" |
26 | 26 | ||
27 | static kmem_cache_t *hfs_inode_cachep; | 27 | static struct kmem_cache *hfs_inode_cachep; |
28 | 28 | ||
29 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
30 | 30 | ||
@@ -145,7 +145,7 @@ static struct inode *hfs_alloc_inode(struct super_block *sb) | |||
145 | { | 145 | { |
146 | struct hfs_inode_info *i; | 146 | struct hfs_inode_info *i; |
147 | 147 | ||
148 | i = kmem_cache_alloc(hfs_inode_cachep, SLAB_KERNEL); | 148 | i = kmem_cache_alloc(hfs_inode_cachep, GFP_KERNEL); |
149 | return i ? &i->vfs_inode : NULL; | 149 | return i ? &i->vfs_inode : NULL; |
150 | } | 150 | } |
151 | 151 | ||
@@ -430,7 +430,7 @@ static struct file_system_type hfs_fs_type = { | |||
430 | .fs_flags = FS_REQUIRES_DEV, | 430 | .fs_flags = FS_REQUIRES_DEV, |
431 | }; | 431 | }; |
432 | 432 | ||
433 | static void hfs_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 433 | static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
434 | { | 434 | { |
435 | struct hfs_inode_info *i = p; | 435 | struct hfs_inode_info *i = p; |
436 | 436 | ||
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 7e309751645f..e886ac8460d3 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -111,7 +111,7 @@ fail: | |||
111 | 111 | ||
112 | static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | 112 | static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) |
113 | { | 113 | { |
114 | struct inode *inode = filp->f_dentry->d_inode; | 114 | struct inode *inode = filp->f_path.dentry->d_inode; |
115 | struct super_block *sb = inode->i_sb; | 115 | struct super_block *sb = inode->i_sb; |
116 | int len, err; | 116 | int len, err; |
117 | char strbuf[HFSPLUS_MAX_STRLEN + 1]; | 117 | char strbuf[HFSPLUS_MAX_STRLEN + 1]; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 9e3675249633..75e8c4d8aac3 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -97,7 +97,7 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb, | |||
97 | const struct iovec *iov, loff_t offset, unsigned long nr_segs) | 97 | const struct iovec *iov, loff_t offset, unsigned long nr_segs) |
98 | { | 98 | { |
99 | struct file *file = iocb->ki_filp; | 99 | struct file *file = iocb->ki_filp; |
100 | struct inode *inode = file->f_dentry->d_inode->i_mapping->host; | 100 | struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; |
101 | 101 | ||
102 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 102 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
103 | offset, nr_segs, hfsplus_get_block, NULL); | 103 | offset, nr_segs, hfsplus_get_block, NULL); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 194eede52fa4..0f513c6bf843 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -434,13 +434,13 @@ MODULE_AUTHOR("Brad Boyer"); | |||
434 | MODULE_DESCRIPTION("Extended Macintosh Filesystem"); | 434 | MODULE_DESCRIPTION("Extended Macintosh Filesystem"); |
435 | MODULE_LICENSE("GPL"); | 435 | MODULE_LICENSE("GPL"); |
436 | 436 | ||
437 | static kmem_cache_t *hfsplus_inode_cachep; | 437 | static struct kmem_cache *hfsplus_inode_cachep; |
438 | 438 | ||
439 | static struct inode *hfsplus_alloc_inode(struct super_block *sb) | 439 | static struct inode *hfsplus_alloc_inode(struct super_block *sb) |
440 | { | 440 | { |
441 | struct hfsplus_inode_info *i; | 441 | struct hfsplus_inode_info *i; |
442 | 442 | ||
443 | i = kmem_cache_alloc(hfsplus_inode_cachep, SLAB_KERNEL); | 443 | i = kmem_cache_alloc(hfsplus_inode_cachep, GFP_KERNEL); |
444 | return i ? &i->vfs_inode : NULL; | 444 | return i ? &i->vfs_inode : NULL; |
445 | } | 445 | } |
446 | 446 | ||
@@ -467,7 +467,7 @@ static struct file_system_type hfsplus_fs_type = { | |||
467 | .fs_flags = FS_REQUIRES_DEV, | 467 | .fs_flags = FS_REQUIRES_DEV, |
468 | }; | 468 | }; |
469 | 469 | ||
470 | static void hfsplus_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 470 | static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
471 | { | 471 | { |
472 | struct hfsplus_inode_info *i = p; | 472 | struct hfsplus_inode_info *i = p; |
473 | 473 | ||
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index b6bd33ca3731..1e6fc3799876 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -35,7 +35,7 @@ static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode) | |||
35 | return(list_entry(inode, struct hostfs_inode_info, vfs_inode)); | 35 | return(list_entry(inode, struct hostfs_inode_info, vfs_inode)); |
36 | } | 36 | } |
37 | 37 | ||
38 | #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode) | 38 | #define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode) |
39 | 39 | ||
40 | int hostfs_d_delete(struct dentry *dentry) | 40 | int hostfs_d_delete(struct dentry *dentry) |
41 | { | 41 | { |
@@ -325,7 +325,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
325 | unsigned long long next, ino; | 325 | unsigned long long next, ino; |
326 | int error, len; | 326 | int error, len; |
327 | 327 | ||
328 | name = dentry_name(file->f_dentry, 0); | 328 | name = dentry_name(file->f_path.dentry, 0); |
329 | if(name == NULL) return(-ENOMEM); | 329 | if(name == NULL) return(-ENOMEM); |
330 | dir = open_dir(name, &error); | 330 | dir = open_dir(name, &error); |
331 | kfree(name); | 331 | kfree(name); |
@@ -366,7 +366,7 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
366 | if(w) | 366 | if(w) |
367 | r = 1; | 367 | r = 1; |
368 | 368 | ||
369 | name = dentry_name(file->f_dentry, 0); | 369 | name = dentry_name(file->f_path.dentry, 0); |
370 | if(name == NULL) | 370 | if(name == NULL) |
371 | return(-ENOMEM); | 371 | return(-ENOMEM); |
372 | 372 | ||
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index ecc9180645ae..6916c41d7017 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -24,7 +24,7 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence) | |||
24 | loff_t new_off = off + (whence == 1 ? filp->f_pos : 0); | 24 | loff_t new_off = off + (whence == 1 ? filp->f_pos : 0); |
25 | loff_t pos; | 25 | loff_t pos; |
26 | struct quad_buffer_head qbh; | 26 | struct quad_buffer_head qbh; |
27 | struct inode *i = filp->f_dentry->d_inode; | 27 | struct inode *i = filp->f_path.dentry->d_inode; |
28 | struct hpfs_inode_info *hpfs_inode = hpfs_i(i); | 28 | struct hpfs_inode_info *hpfs_inode = hpfs_i(i); |
29 | struct super_block *s = i->i_sb; | 29 | struct super_block *s = i->i_sb; |
30 | 30 | ||
@@ -52,7 +52,7 @@ fail: | |||
52 | 52 | ||
53 | static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 53 | static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
54 | { | 54 | { |
55 | struct inode *inode = filp->f_dentry->d_inode; | 55 | struct inode *inode = filp->f_path.dentry->d_inode; |
56 | struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); | 56 | struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); |
57 | struct quad_buffer_head qbh; | 57 | struct quad_buffer_head qbh; |
58 | struct hpfs_dirent *de; | 58 | struct hpfs_dirent *de; |
@@ -84,7 +84,8 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
84 | } | 84 | } |
85 | if (!fno->dirflag) { | 85 | if (!fno->dirflag) { |
86 | e = 1; | 86 | e = 1; |
87 | hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino); | 87 | hpfs_error(inode->i_sb, "not a directory, fnode %08lx", |
88 | (unsigned long)inode->i_ino); | ||
88 | } | 89 | } |
89 | if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { | 90 | if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { |
90 | e = 1; | 91 | e = 1; |
@@ -144,8 +145,11 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
144 | } | 145 | } |
145 | if (de->first || de->last) { | 146 | if (de->first || de->last) { |
146 | if (hpfs_sb(inode->i_sb)->sb_chk) { | 147 | if (hpfs_sb(inode->i_sb)->sb_chk) { |
147 | if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos); | 148 | if (de->first && !de->last && (de->namelen != 2 |
148 | if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos); | 149 | || de ->name[0] != 1 || de->name[1] != 1)) |
150 | hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08lx", old_pos); | ||
151 | if (de->last && (de->namelen != 1 || de ->name[0] != 255)) | ||
152 | hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08lx", old_pos); | ||
149 | } | 153 | } |
150 | hpfs_brelse4(&qbh); | 154 | hpfs_brelse4(&qbh); |
151 | goto again; | 155 | goto again; |
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 229ff2fb1809..fe83c2b7d2d8 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c | |||
@@ -533,10 +533,13 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
533 | struct buffer_head *bh; | 533 | struct buffer_head *bh; |
534 | struct dnode *d1; | 534 | struct dnode *d1; |
535 | struct quad_buffer_head qbh1; | 535 | struct quad_buffer_head qbh1; |
536 | if (hpfs_sb(i->i_sb)->sb_chk) if (up != i->i_ino) { | 536 | if (hpfs_sb(i->i_sb)->sb_chk) |
537 | hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino); | 537 | if (up != i->i_ino) { |
538 | hpfs_error(i->i_sb, | ||
539 | "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08lx", | ||
540 | dno, up, (unsigned long)i->i_ino); | ||
538 | return; | 541 | return; |
539 | } | 542 | } |
540 | if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { | 543 | if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { |
541 | d1->up = up; | 544 | d1->up = up; |
542 | d1->root_dnode = 1; | 545 | d1->root_dnode = 1; |
@@ -851,7 +854,9 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, | |||
851 | /* Going to the next dirent */ | 854 | /* Going to the next dirent */ |
852 | if ((d = de_next_de(de)) < dnode_end_de(dnode)) { | 855 | if ((d = de_next_de(de)) < dnode_end_de(dnode)) { |
853 | if (!(++*posp & 077)) { | 856 | if (!(++*posp & 077)) { |
854 | hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp); | 857 | hpfs_error(inode->i_sb, |
858 | "map_pos_dirent: pos crossed dnode boundary; pos = %08llx", | ||
859 | (unsigned long long)*posp); | ||
855 | goto bail; | 860 | goto bail; |
856 | } | 861 | } |
857 | /* We're going down the tree */ | 862 | /* We're going down the tree */ |
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index 66339dc030e4..547a8384571f 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c | |||
@@ -243,8 +243,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, char *key, char *data | |||
243 | fnode->ea_offs = 0xc4; | 243 | fnode->ea_offs = 0xc4; |
244 | } | 244 | } |
245 | if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { | 245 | if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { |
246 | hpfs_error(s, "fnode %08x: ea_offs == %03x, ea_size_s == %03x", | 246 | hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", |
247 | inode->i_ino, fnode->ea_offs, fnode->ea_size_s); | 247 | (unsigned long)inode->i_ino, |
248 | fnode->ea_offs, fnode->ea_size_s); | ||
248 | return; | 249 | return; |
249 | } | 250 | } |
250 | if ((fnode->ea_size_s || !fnode->ea_size_l) && | 251 | if ((fnode->ea_size_s || !fnode->ea_size_l) && |
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 8b94d24855f0..fb4c8915010a 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c | |||
@@ -115,7 +115,7 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, | |||
115 | 115 | ||
116 | retval = do_sync_write(file, buf, count, ppos); | 116 | retval = do_sync_write(file, buf, count, ppos); |
117 | if (retval > 0) | 117 | if (retval > 0) |
118 | hpfs_i(file->f_dentry->d_inode)->i_dirty = 1; | 118 | hpfs_i(file->f_path.dentry->d_inode)->i_dirty = 1; |
119 | return retval; | 119 | return retval; |
120 | } | 120 | } |
121 | 121 | ||
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 32ab51e42b96..1c07aa82d327 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -317,7 +317,8 @@ static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb) | |||
317 | 317 | ||
318 | /* super.c */ | 318 | /* super.c */ |
319 | 319 | ||
320 | void hpfs_error(struct super_block *, char *, ...); | 320 | void hpfs_error(struct super_block *, const char *, ...) |
321 | __attribute__((format (printf, 2, 3))); | ||
321 | int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); | 322 | int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); |
322 | unsigned hpfs_count_one_bitmap(struct super_block *, secno); | 323 | unsigned hpfs_count_one_bitmap(struct super_block *, secno); |
323 | 324 | ||
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 7faef8544f32..85d3e1d9ac00 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -251,7 +251,10 @@ void hpfs_write_inode_nolock(struct inode *i) | |||
251 | de->file_size = 0; | 251 | de->file_size = 0; |
252 | hpfs_mark_4buffers_dirty(&qbh); | 252 | hpfs_mark_4buffers_dirty(&qbh); |
253 | hpfs_brelse4(&qbh); | 253 | hpfs_brelse4(&qbh); |
254 | } else hpfs_error(i->i_sb, "directory %08x doesn't have '.' entry", i->i_ino); | 254 | } else |
255 | hpfs_error(i->i_sb, | ||
256 | "directory %08lx doesn't have '.' entry", | ||
257 | (unsigned long)i->i_ino); | ||
255 | } | 258 | } |
256 | mark_buffer_dirty(bh); | 259 | mark_buffer_dirty(bh); |
257 | brelse(bh); | 260 | brelse(bh); |
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index 0fecdac22e4e..c4724589b2eb 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c | |||
@@ -126,32 +126,40 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea | |||
126 | struct extended_attribute *ea; | 126 | struct extended_attribute *ea; |
127 | struct extended_attribute *ea_end; | 127 | struct extended_attribute *ea_end; |
128 | if (fnode->magic != FNODE_MAGIC) { | 128 | if (fnode->magic != FNODE_MAGIC) { |
129 | hpfs_error(s, "bad magic on fnode %08x", ino); | 129 | hpfs_error(s, "bad magic on fnode %08lx", |
130 | (unsigned long)ino); | ||
130 | goto bail; | 131 | goto bail; |
131 | } | 132 | } |
132 | if (!fnode->dirflag) { | 133 | if (!fnode->dirflag) { |
133 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != | 134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != |
134 | (fnode->btree.internal ? 12 : 8)) { | 135 | (fnode->btree.internal ? 12 : 8)) { |
135 | hpfs_error(s, "bad number of nodes in fnode %08x", ino); | 136 | hpfs_error(s, |
137 | "bad number of nodes in fnode %08lx", | ||
138 | (unsigned long)ino); | ||
136 | goto bail; | 139 | goto bail; |
137 | } | 140 | } |
138 | if (fnode->btree.first_free != | 141 | if (fnode->btree.first_free != |
139 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { | 142 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { |
140 | hpfs_error(s, "bad first_free pointer in fnode %08x", ino); | 143 | hpfs_error(s, |
144 | "bad first_free pointer in fnode %08lx", | ||
145 | (unsigned long)ino); | ||
141 | goto bail; | 146 | goto bail; |
142 | } | 147 | } |
143 | } | 148 | } |
144 | if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || | 149 | if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || |
145 | (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { | 150 | (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { |
146 | hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x", | 151 | hpfs_error(s, |
147 | ino, fnode->ea_offs, fnode->ea_size_s); | 152 | "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x", |
153 | (unsigned long)ino, | ||
154 | fnode->ea_offs, fnode->ea_size_s); | ||
148 | goto bail; | 155 | goto bail; |
149 | } | 156 | } |
150 | ea = fnode_ea(fnode); | 157 | ea = fnode_ea(fnode); |
151 | ea_end = fnode_end_ea(fnode); | 158 | ea_end = fnode_end_ea(fnode); |
152 | while (ea != ea_end) { | 159 | while (ea != ea_end) { |
153 | if (ea > ea_end) { | 160 | if (ea > ea_end) { |
154 | hpfs_error(s, "bad EA in fnode %08x", ino); | 161 | hpfs_error(s, "bad EA in fnode %08lx", |
162 | (unsigned long)ino); | ||
155 | goto bail; | 163 | goto bail; |
156 | } | 164 | } |
157 | ea = next_ea(ea); | 165 | ea = next_ea(ea); |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 450b5e0b4785..d4abc1a1d566 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -46,21 +46,17 @@ static void unmark_dirty(struct super_block *s) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | /* Filesystem error... */ | 48 | /* Filesystem error... */ |
49 | static char err_buf[1024]; | ||
49 | 50 | ||
50 | #define ERR_BUF_SIZE 1024 | 51 | void hpfs_error(struct super_block *s, const char *fmt, ...) |
51 | |||
52 | void hpfs_error(struct super_block *s, char *m,...) | ||
53 | { | 52 | { |
54 | char *buf; | 53 | va_list args; |
55 | va_list l; | 54 | |
56 | va_start(l, m); | 55 | va_start(args, fmt); |
57 | if (!(buf = kmalloc(ERR_BUF_SIZE, GFP_KERNEL))) | 56 | vsnprintf(err_buf, sizeof(err_buf), fmt, args); |
58 | printk("HPFS: No memory for error message '%s'\n",m); | 57 | va_end(args); |
59 | else if (vsprintf(buf, m, l) >= ERR_BUF_SIZE) | 58 | |
60 | printk("HPFS: Grrrr... Kernel memory corrupted ... going on, but it'll crash very soon :-(\n"); | 59 | printk("HPFS: filesystem error: %s", err_buf); |
61 | printk("HPFS: filesystem error: "); | ||
62 | if (buf) printk("%s", buf); | ||
63 | else printk("%s\n",m); | ||
64 | if (!hpfs_sb(s)->sb_was_error) { | 60 | if (!hpfs_sb(s)->sb_was_error) { |
65 | if (hpfs_sb(s)->sb_err == 2) { | 61 | if (hpfs_sb(s)->sb_err == 2) { |
66 | printk("; crashing the system because you wanted it\n"); | 62 | printk("; crashing the system because you wanted it\n"); |
@@ -76,7 +72,6 @@ void hpfs_error(struct super_block *s, char *m,...) | |||
76 | } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); | 72 | } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); |
77 | else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); | 73 | else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); |
78 | } else printk("\n"); | 74 | } else printk("\n"); |
79 | kfree(buf); | ||
80 | hpfs_sb(s)->sb_was_error = 1; | 75 | hpfs_sb(s)->sb_was_error = 1; |
81 | } | 76 | } |
82 | 77 | ||
@@ -160,12 +155,12 @@ static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
160 | return 0; | 155 | return 0; |
161 | } | 156 | } |
162 | 157 | ||
163 | static kmem_cache_t * hpfs_inode_cachep; | 158 | static struct kmem_cache * hpfs_inode_cachep; |
164 | 159 | ||
165 | static struct inode *hpfs_alloc_inode(struct super_block *sb) | 160 | static struct inode *hpfs_alloc_inode(struct super_block *sb) |
166 | { | 161 | { |
167 | struct hpfs_inode_info *ei; | 162 | struct hpfs_inode_info *ei; |
168 | ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_NOFS); | 163 | ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, GFP_NOFS); |
169 | if (!ei) | 164 | if (!ei) |
170 | return NULL; | 165 | return NULL; |
171 | ei->vfs_inode.i_version = 1; | 166 | ei->vfs_inode.i_version = 1; |
@@ -177,7 +172,7 @@ static void hpfs_destroy_inode(struct inode *inode) | |||
177 | kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); | 172 | kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); |
178 | } | 173 | } |
179 | 174 | ||
180 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 175 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
181 | { | 176 | { |
182 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; | 177 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; |
183 | 178 | ||
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index 642675fc394a..afd340a45da4 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c | |||
@@ -221,7 +221,7 @@ static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count, | |||
221 | ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); | 221 | ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); |
222 | ssize_t n; | 222 | ssize_t n; |
223 | 223 | ||
224 | read = file->f_dentry->d_inode->i_fop->read; | 224 | read = file->f_path.dentry->d_inode->i_fop->read; |
225 | 225 | ||
226 | if(!is_user) | 226 | if(!is_user) |
227 | set_fs(KERNEL_DS); | 227 | set_fs(KERNEL_DS); |
@@ -320,7 +320,7 @@ static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len | |||
320 | ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); | 320 | ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); |
321 | int err; | 321 | int err; |
322 | 322 | ||
323 | write = proc_file->f_dentry->d_inode->i_fop->write; | 323 | write = proc_file->f_path.dentry->d_inode->i_fop->write; |
324 | 324 | ||
325 | proc_file->f_pos = file->f_pos; | 325 | proc_file->f_pos = file->f_pos; |
326 | err = (*write)(proc_file, buf, len, &proc_file->f_pos); | 326 | err = (*write)(proc_file, buf, len, &proc_file->f_pos); |
@@ -464,7 +464,7 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
464 | if(data == NULL) | 464 | if(data == NULL) |
465 | goto out; | 465 | goto out; |
466 | 466 | ||
467 | host_file = dentry_name(file->f_dentry, strlen("/rw")); | 467 | host_file = dentry_name(file->f_path.dentry, strlen("/rw")); |
468 | if(host_file == NULL) | 468 | if(host_file == NULL) |
469 | goto out_free2; | 469 | goto out_free2; |
470 | 470 | ||
@@ -547,7 +547,7 @@ static loff_t hppfs_llseek(struct file *file, loff_t off, int where) | |||
547 | loff_t (*llseek)(struct file *, loff_t, int); | 547 | loff_t (*llseek)(struct file *, loff_t, int); |
548 | loff_t ret; | 548 | loff_t ret; |
549 | 549 | ||
550 | llseek = proc_file->f_dentry->d_inode->i_fop->llseek; | 550 | llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek; |
551 | if(llseek != NULL){ | 551 | if(llseek != NULL){ |
552 | ret = (*llseek)(proc_file, off, where); | 552 | ret = (*llseek)(proc_file, off, where); |
553 | if(ret < 0) | 553 | if(ret < 0) |
@@ -591,10 +591,10 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
591 | struct hppfs_dirent dirent = ((struct hppfs_dirent) | 591 | struct hppfs_dirent dirent = ((struct hppfs_dirent) |
592 | { .vfs_dirent = ent, | 592 | { .vfs_dirent = ent, |
593 | .filldir = filldir, | 593 | .filldir = filldir, |
594 | .dentry = file->f_dentry } ); | 594 | .dentry = file->f_path.dentry } ); |
595 | int err; | 595 | int err; |
596 | 596 | ||
597 | readdir = proc_file->f_dentry->d_inode->i_fop->readdir; | 597 | readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir; |
598 | 598 | ||
599 | proc_file->f_pos = file->f_pos; | 599 | proc_file->f_pos = file->f_pos; |
600 | err = (*readdir)(proc_file, &dirent, hppfs_filldir); | 600 | err = (*readdir)(proc_file, &dirent, hppfs_filldir); |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7f4756963d05..4f4cd132b571 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -58,7 +58,7 @@ static void huge_pagevec_release(struct pagevec *pvec) | |||
58 | 58 | ||
59 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 59 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
60 | { | 60 | { |
61 | struct inode *inode = file->f_dentry->d_inode; | 61 | struct inode *inode = file->f_path.dentry->d_inode; |
62 | loff_t len, vma_len; | 62 | loff_t len, vma_len; |
63 | int ret; | 63 | int ret; |
64 | 64 | ||
@@ -176,7 +176,7 @@ static int hugetlbfs_commit_write(struct file *file, | |||
176 | 176 | ||
177 | static void truncate_huge_page(struct page *page) | 177 | static void truncate_huge_page(struct page *page) |
178 | { | 178 | { |
179 | clear_page_dirty(page); | 179 | cancel_dirty_page(page, /* No IO accounting for huge pages? */0); |
180 | ClearPageUptodate(page); | 180 | ClearPageUptodate(page); |
181 | remove_from_page_cache(page); | 181 | remove_from_page_cache(page); |
182 | put_page(page); | 182 | put_page(page); |
@@ -513,7 +513,7 @@ static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo) | |||
513 | } | 513 | } |
514 | 514 | ||
515 | 515 | ||
516 | static kmem_cache_t *hugetlbfs_inode_cachep; | 516 | static struct kmem_cache *hugetlbfs_inode_cachep; |
517 | 517 | ||
518 | static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) | 518 | static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) |
519 | { | 519 | { |
@@ -522,7 +522,7 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) | |||
522 | 522 | ||
523 | if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo))) | 523 | if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo))) |
524 | return NULL; | 524 | return NULL; |
525 | p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL); | 525 | p = kmem_cache_alloc(hugetlbfs_inode_cachep, GFP_KERNEL); |
526 | if (unlikely(!p)) { | 526 | if (unlikely(!p)) { |
527 | hugetlbfs_inc_free_inodes(sbinfo); | 527 | hugetlbfs_inc_free_inodes(sbinfo); |
528 | return NULL; | 528 | return NULL; |
@@ -545,7 +545,7 @@ static const struct address_space_operations hugetlbfs_aops = { | |||
545 | }; | 545 | }; |
546 | 546 | ||
547 | 547 | ||
548 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 548 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
549 | { | 549 | { |
550 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; | 550 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; |
551 | 551 | ||
@@ -774,8 +774,8 @@ struct file *hugetlb_zero_setup(size_t size) | |||
774 | d_instantiate(dentry, inode); | 774 | d_instantiate(dentry, inode); |
775 | inode->i_size = size; | 775 | inode->i_size = size; |
776 | inode->i_nlink = 0; | 776 | inode->i_nlink = 0; |
777 | file->f_vfsmnt = mntget(hugetlbfs_vfsmount); | 777 | file->f_path.mnt = mntget(hugetlbfs_vfsmount); |
778 | file->f_dentry = dentry; | 778 | file->f_path.dentry = dentry; |
779 | file->f_mapping = inode->i_mapping; | 779 | file->f_mapping = inode->i_mapping; |
780 | file->f_op = &hugetlbfs_file_operations; | 780 | file->f_op = &hugetlbfs_file_operations; |
781 | file->f_mode = FMODE_WRITE | FMODE_READ; | 781 | file->f_mode = FMODE_WRITE | FMODE_READ; |
diff --git a/fs/inode.c b/fs/inode.c index 26cdb115ce67..bf21dc6d0dbd 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -97,7 +97,7 @@ static DEFINE_MUTEX(iprune_mutex); | |||
97 | */ | 97 | */ |
98 | struct inodes_stat_t inodes_stat; | 98 | struct inodes_stat_t inodes_stat; |
99 | 99 | ||
100 | static kmem_cache_t * inode_cachep __read_mostly; | 100 | static struct kmem_cache * inode_cachep __read_mostly; |
101 | 101 | ||
102 | static struct inode *alloc_inode(struct super_block *sb) | 102 | static struct inode *alloc_inode(struct super_block *sb) |
103 | { | 103 | { |
@@ -109,7 +109,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
109 | if (sb->s_op->alloc_inode) | 109 | if (sb->s_op->alloc_inode) |
110 | inode = sb->s_op->alloc_inode(sb); | 110 | inode = sb->s_op->alloc_inode(sb); |
111 | else | 111 | else |
112 | inode = (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL); | 112 | inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL); |
113 | 113 | ||
114 | if (inode) { | 114 | if (inode) { |
115 | struct address_space * const mapping = &inode->i_data; | 115 | struct address_space * const mapping = &inode->i_data; |
@@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) | |||
209 | 209 | ||
210 | EXPORT_SYMBOL(inode_init_once); | 210 | EXPORT_SYMBOL(inode_init_once); |
211 | 211 | ||
212 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 212 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
213 | { | 213 | { |
214 | struct inode * inode = (struct inode *) foo; | 214 | struct inode * inode = (struct inode *) foo; |
215 | 215 | ||
@@ -1144,7 +1144,6 @@ sector_t bmap(struct inode * inode, sector_t block) | |||
1144 | res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block); | 1144 | res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block); |
1145 | return res; | 1145 | return res; |
1146 | } | 1146 | } |
1147 | |||
1148 | EXPORT_SYMBOL(bmap); | 1147 | EXPORT_SYMBOL(bmap); |
1149 | 1148 | ||
1150 | /** | 1149 | /** |
@@ -1163,27 +1162,43 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) | |||
1163 | 1162 | ||
1164 | if (IS_RDONLY(inode)) | 1163 | if (IS_RDONLY(inode)) |
1165 | return; | 1164 | return; |
1166 | 1165 | if (inode->i_flags & S_NOATIME) | |
1167 | if ((inode->i_flags & S_NOATIME) || | 1166 | return; |
1168 | (inode->i_sb->s_flags & MS_NOATIME) || | 1167 | if (inode->i_sb->s_flags & MS_NOATIME) |
1169 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) | 1168 | return; |
1169 | if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) | ||
1170 | return; | 1170 | return; |
1171 | 1171 | ||
1172 | /* | 1172 | /* |
1173 | * We may have a NULL vfsmount when coming from NFSD | 1173 | * We may have a NULL vfsmount when coming from NFSD |
1174 | */ | 1174 | */ |
1175 | if (mnt && | 1175 | if (mnt) { |
1176 | ((mnt->mnt_flags & MNT_NOATIME) || | 1176 | if (mnt->mnt_flags & MNT_NOATIME) |
1177 | ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))) | 1177 | return; |
1178 | return; | 1178 | if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) |
1179 | return; | ||
1179 | 1180 | ||
1180 | now = current_fs_time(inode->i_sb); | 1181 | if (mnt->mnt_flags & MNT_RELATIME) { |
1181 | if (!timespec_equal(&inode->i_atime, &now)) { | 1182 | /* |
1182 | inode->i_atime = now; | 1183 | * With relative atime, only update atime if the |
1183 | mark_inode_dirty_sync(inode); | 1184 | * previous atime is earlier than either the ctime or |
1185 | * mtime. | ||
1186 | */ | ||
1187 | if (timespec_compare(&inode->i_mtime, | ||
1188 | &inode->i_atime) < 0 && | ||
1189 | timespec_compare(&inode->i_ctime, | ||
1190 | &inode->i_atime) < 0) | ||
1191 | return; | ||
1192 | } | ||
1184 | } | 1193 | } |
1185 | } | ||
1186 | 1194 | ||
1195 | now = current_fs_time(inode->i_sb); | ||
1196 | if (timespec_equal(&inode->i_atime, &now)) | ||
1197 | return; | ||
1198 | |||
1199 | inode->i_atime = now; | ||
1200 | mark_inode_dirty_sync(inode); | ||
1201 | } | ||
1187 | EXPORT_SYMBOL(touch_atime); | 1202 | EXPORT_SYMBOL(touch_atime); |
1188 | 1203 | ||
1189 | /** | 1204 | /** |
@@ -1200,7 +1215,7 @@ EXPORT_SYMBOL(touch_atime); | |||
1200 | 1215 | ||
1201 | void file_update_time(struct file *file) | 1216 | void file_update_time(struct file *file) |
1202 | { | 1217 | { |
1203 | struct inode *inode = file->f_dentry->d_inode; | 1218 | struct inode *inode = file->f_path.dentry->d_inode; |
1204 | struct timespec now; | 1219 | struct timespec now; |
1205 | int sync_it = 0; | 1220 | int sync_it = 0; |
1206 | 1221 | ||
@@ -1242,9 +1257,6 @@ EXPORT_SYMBOL(inode_needs_sync); | |||
1242 | */ | 1257 | */ |
1243 | #ifdef CONFIG_QUOTA | 1258 | #ifdef CONFIG_QUOTA |
1244 | 1259 | ||
1245 | /* Function back in dquot.c */ | ||
1246 | int remove_inode_dquot_ref(struct inode *, int, struct list_head *); | ||
1247 | |||
1248 | void remove_dquot_ref(struct super_block *sb, int type, | 1260 | void remove_dquot_ref(struct super_block *sb, int type, |
1249 | struct list_head *tofree_head) | 1261 | struct list_head *tofree_head) |
1250 | { | 1262 | { |
diff --git a/fs/inotify.c b/fs/inotify.c index 723836a1f718..f5099d86fd91 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/list.h> | 32 | #include <linux/list.h> |
32 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 017cb0f134d6..55f6da55b7c0 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -34,8 +34,8 @@ | |||
34 | 34 | ||
35 | #include <asm/ioctls.h> | 35 | #include <asm/ioctls.h> |
36 | 36 | ||
37 | static kmem_cache_t *watch_cachep __read_mostly; | 37 | static struct kmem_cache *watch_cachep __read_mostly; |
38 | static kmem_cache_t *event_cachep __read_mostly; | 38 | static struct kmem_cache *event_cachep __read_mostly; |
39 | 39 | ||
40 | static struct vfsmount *inotify_mnt __read_mostly; | 40 | static struct vfsmount *inotify_mnt __read_mostly; |
41 | 41 | ||
@@ -570,9 +570,9 @@ asmlinkage long sys_inotify_init(void) | |||
570 | dev->ih = ih; | 570 | dev->ih = ih; |
571 | 571 | ||
572 | filp->f_op = &inotify_fops; | 572 | filp->f_op = &inotify_fops; |
573 | filp->f_vfsmnt = mntget(inotify_mnt); | 573 | filp->f_path.mnt = mntget(inotify_mnt); |
574 | filp->f_dentry = dget(inotify_mnt->mnt_root); | 574 | filp->f_path.dentry = dget(inotify_mnt->mnt_root); |
575 | filp->f_mapping = filp->f_dentry->d_inode->i_mapping; | 575 | filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping; |
576 | filp->f_mode = FMODE_READ; | 576 | filp->f_mode = FMODE_READ; |
577 | filp->f_flags = O_RDONLY; | 577 | filp->f_flags = O_RDONLY; |
578 | filp->private_data = dev; | 578 | filp->private_data = dev; |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 4b7660b09ac0..ff61772ceedd 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -31,7 +31,7 @@ static long do_ioctl(struct file *filp, unsigned int cmd, | |||
31 | goto out; | 31 | goto out; |
32 | } else if (filp->f_op->ioctl) { | 32 | } else if (filp->f_op->ioctl) { |
33 | lock_kernel(); | 33 | lock_kernel(); |
34 | error = filp->f_op->ioctl(filp->f_dentry->d_inode, | 34 | error = filp->f_op->ioctl(filp->f_path.dentry->d_inode, |
35 | filp, cmd, arg); | 35 | filp, cmd, arg); |
36 | unlock_kernel(); | 36 | unlock_kernel(); |
37 | } | 37 | } |
@@ -45,7 +45,7 @@ static int file_ioctl(struct file *filp, unsigned int cmd, | |||
45 | { | 45 | { |
46 | int error; | 46 | int error; |
47 | int block; | 47 | int block; |
48 | struct inode * inode = filp->f_dentry->d_inode; | 48 | struct inode * inode = filp->f_path.dentry->d_inode; |
49 | int __user *p = (int __user *)arg; | 49 | int __user *p = (int __user *)arg; |
50 | 50 | ||
51 | switch (cmd) { | 51 | switch (cmd) { |
@@ -137,17 +137,17 @@ int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned lon | |||
137 | break; | 137 | break; |
138 | 138 | ||
139 | case FIOQSIZE: | 139 | case FIOQSIZE: |
140 | if (S_ISDIR(filp->f_dentry->d_inode->i_mode) || | 140 | if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) || |
141 | S_ISREG(filp->f_dentry->d_inode->i_mode) || | 141 | S_ISREG(filp->f_path.dentry->d_inode->i_mode) || |
142 | S_ISLNK(filp->f_dentry->d_inode->i_mode)) { | 142 | S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) { |
143 | loff_t res = inode_get_bytes(filp->f_dentry->d_inode); | 143 | loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode); |
144 | error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; | 144 | error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0; |
145 | } | 145 | } |
146 | else | 146 | else |
147 | error = -ENOTTY; | 147 | error = -ENOTTY; |
148 | break; | 148 | break; |
149 | default: | 149 | default: |
150 | if (S_ISREG(filp->f_dentry->d_inode->i_mode)) | 150 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) |
151 | error = file_ioctl(filp, cmd, arg); | 151 | error = file_ioctl(filp, cmd, arg); |
152 | else | 152 | else |
153 | error = do_ioctl(filp, cmd, arg); | 153 | error = do_ioctl(filp, cmd, arg); |
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index 731816332b12..6bbbdb53581d 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c | |||
@@ -42,7 +42,7 @@ static struct semaphore zisofs_zlib_semaphore; | |||
42 | */ | 42 | */ |
43 | static int zisofs_readpage(struct file *file, struct page *page) | 43 | static int zisofs_readpage(struct file *file, struct page *page) |
44 | { | 44 | { |
45 | struct inode *inode = file->f_dentry->d_inode; | 45 | struct inode *inode = file->f_path.dentry->d_inode; |
46 | struct address_space *mapping = inode->i_mapping; | 46 | struct address_space *mapping = inode->i_mapping; |
47 | unsigned int maxpage, xpage, fpage, blockindex; | 47 | unsigned int maxpage, xpage, fpage, blockindex; |
48 | unsigned long offset; | 48 | unsigned long offset; |
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 27e276987fd2..4af2548f97a9 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c | |||
@@ -183,7 +183,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp, | |||
183 | 183 | ||
184 | /* Handle the case of the '..' directory */ | 184 | /* Handle the case of the '..' directory */ |
185 | if (de->name_len[0] == 1 && de->name[0] == 1) { | 185 | if (de->name_len[0] == 1 && de->name[0] == 1) { |
186 | inode_number = parent_ino(filp->f_dentry); | 186 | inode_number = parent_ino(filp->f_path.dentry); |
187 | if (filldir(dirent, "..", 2, filp->f_pos, inode_number, DT_DIR) < 0) | 187 | if (filldir(dirent, "..", 2, filp->f_pos, inode_number, DT_DIR) < 0) |
188 | break; | 188 | break; |
189 | filp->f_pos += de_len; | 189 | filp->f_pos += de_len; |
@@ -255,8 +255,7 @@ static int isofs_readdir(struct file *filp, | |||
255 | int result; | 255 | int result; |
256 | char * tmpname; | 256 | char * tmpname; |
257 | struct iso_directory_record * tmpde; | 257 | struct iso_directory_record * tmpde; |
258 | struct inode *inode = filp->f_dentry->d_inode; | 258 | struct inode *inode = filp->f_path.dentry->d_inode; |
259 | |||
260 | 259 | ||
261 | tmpname = (char *)__get_free_page(GFP_KERNEL); | 260 | tmpname = (char *)__get_free_page(GFP_KERNEL); |
262 | if (tmpname == NULL) | 261 | if (tmpname == NULL) |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index c34b862cdbf2..ea55b6c469ec 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -57,12 +57,12 @@ static void isofs_put_super(struct super_block *sb) | |||
57 | static void isofs_read_inode(struct inode *); | 57 | static void isofs_read_inode(struct inode *); |
58 | static int isofs_statfs (struct dentry *, struct kstatfs *); | 58 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
59 | 59 | ||
60 | static kmem_cache_t *isofs_inode_cachep; | 60 | static struct kmem_cache *isofs_inode_cachep; |
61 | 61 | ||
62 | static struct inode *isofs_alloc_inode(struct super_block *sb) | 62 | static struct inode *isofs_alloc_inode(struct super_block *sb) |
63 | { | 63 | { |
64 | struct iso_inode_info *ei; | 64 | struct iso_inode_info *ei; |
65 | ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); | 65 | ei = kmem_cache_alloc(isofs_inode_cachep, GFP_KERNEL); |
66 | if (!ei) | 66 | if (!ei) |
67 | return NULL; | 67 | return NULL; |
68 | return &ei->vfs_inode; | 68 | return &ei->vfs_inode; |
@@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode) | |||
73 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); | 73 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); |
74 | } | 74 | } |
75 | 75 | ||
76 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 76 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
77 | { | 77 | { |
78 | struct iso_inode_info *ei = foo; | 78 | struct iso_inode_info *ei = foo; |
79 | 79 | ||
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 10be51290a27..be4648bc7a2f 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -248,8 +248,12 @@ write_out_data: | |||
248 | bufs = 0; | 248 | bufs = 0; |
249 | goto write_out_data; | 249 | goto write_out_data; |
250 | } | 250 | } |
251 | } | 251 | } else if (!locked && buffer_locked(bh)) { |
252 | else { | 252 | __journal_file_buffer(jh, commit_transaction, |
253 | BJ_Locked); | ||
254 | jbd_unlock_bh_state(bh); | ||
255 | put_bh(bh); | ||
256 | } else { | ||
253 | BUFFER_TRACE(bh, "writeout complete: unfile"); | 257 | BUFFER_TRACE(bh, "writeout complete: unfile"); |
254 | __journal_unfile_buffer(jh); | 258 | __journal_unfile_buffer(jh); |
255 | jbd_unlock_bh_state(bh); | 259 | jbd_unlock_bh_state(bh); |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index b85c686b60db..10fff9443938 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/suspend.h> | 34 | #include <linux/freezer.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/poison.h> | 37 | #include <linux/poison.h> |
@@ -1630,7 +1630,7 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | |||
1630 | #define JBD_MAX_SLABS 5 | 1630 | #define JBD_MAX_SLABS 5 |
1631 | #define JBD_SLAB_INDEX(size) (size >> 11) | 1631 | #define JBD_SLAB_INDEX(size) (size >> 11) |
1632 | 1632 | ||
1633 | static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; | 1633 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; |
1634 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | 1634 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { |
1635 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" | 1635 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" |
1636 | }; | 1636 | }; |
@@ -1693,7 +1693,7 @@ void jbd_slab_free(void *ptr, size_t size) | |||
1693 | /* | 1693 | /* |
1694 | * Journal_head storage management | 1694 | * Journal_head storage management |
1695 | */ | 1695 | */ |
1696 | static kmem_cache_t *journal_head_cache; | 1696 | static struct kmem_cache *journal_head_cache; |
1697 | #ifdef CONFIG_JBD_DEBUG | 1697 | #ifdef CONFIG_JBD_DEBUG |
1698 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); | 1698 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
1699 | #endif | 1699 | #endif |
@@ -1996,7 +1996,7 @@ static void __exit remove_jbd_proc_entry(void) | |||
1996 | 1996 | ||
1997 | #endif | 1997 | #endif |
1998 | 1998 | ||
1999 | kmem_cache_t *jbd_handle_cache; | 1999 | struct kmem_cache *jbd_handle_cache; |
2000 | 2000 | ||
2001 | static int __init journal_init_handle_cache(void) | 2001 | static int __init journal_init_handle_cache(void) |
2002 | { | 2002 | { |
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index c532429d8d9b..d204ab394f36 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -70,8 +70,8 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | static kmem_cache_t *revoke_record_cache; | 73 | static struct kmem_cache *revoke_record_cache; |
74 | static kmem_cache_t *revoke_table_cache; | 74 | static struct kmem_cache *revoke_table_cache; |
75 | 75 | ||
76 | /* Each revoke record represents one single revoked block. During | 76 | /* Each revoke record represents one single revoked block. During |
77 | journal replay, this involves recording the transaction ID of the | 77 | journal replay, this involves recording the transaction ID of the |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 4f82bcd63e48..cceaf57e3778 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | 29 | ||
30 | static void __journal_temp_unlink_buffer(struct journal_head *jh); | ||
31 | |||
30 | /* | 32 | /* |
31 | * get_transaction: obtain a new transaction_t object. | 33 | * get_transaction: obtain a new transaction_t object. |
32 | * | 34 | * |
@@ -53,7 +55,7 @@ get_transaction(journal_t *journal, transaction_t *transaction) | |||
53 | spin_lock_init(&transaction->t_handle_lock); | 55 | spin_lock_init(&transaction->t_handle_lock); |
54 | 56 | ||
55 | /* Set up the commit timer for the new transaction. */ | 57 | /* Set up the commit timer for the new transaction. */ |
56 | journal->j_commit_timer.expires = transaction->t_expires; | 58 | journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); |
57 | add_timer(&journal->j_commit_timer); | 59 | add_timer(&journal->j_commit_timer); |
58 | 60 | ||
59 | J_ASSERT(journal->j_running_transaction == NULL); | 61 | J_ASSERT(journal->j_running_transaction == NULL); |
@@ -1499,7 +1501,7 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh) | |||
1499 | * | 1501 | * |
1500 | * Called under j_list_lock. The journal may not be locked. | 1502 | * Called under j_list_lock. The journal may not be locked. |
1501 | */ | 1503 | */ |
1502 | void __journal_temp_unlink_buffer(struct journal_head *jh) | 1504 | static void __journal_temp_unlink_buffer(struct journal_head *jh) |
1503 | { | 1505 | { |
1504 | struct journal_head **list = NULL; | 1506 | struct journal_head **list = NULL; |
1505 | transaction_t *transaction; | 1507 | transaction_t *transaction; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 70b2ae1ef281..6bd8005e3d34 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -248,8 +248,12 @@ write_out_data: | |||
248 | bufs = 0; | 248 | bufs = 0; |
249 | goto write_out_data; | 249 | goto write_out_data; |
250 | } | 250 | } |
251 | } | 251 | } else if (!locked && buffer_locked(bh)) { |
252 | else { | 252 | __jbd2_journal_file_buffer(jh, commit_transaction, |
253 | BJ_Locked); | ||
254 | jbd_unlock_bh_state(bh); | ||
255 | put_bh(bh); | ||
256 | } else { | ||
253 | BUFFER_TRACE(bh, "writeout complete: unfile"); | 257 | BUFFER_TRACE(bh, "writeout complete: unfile"); |
254 | __jbd2_journal_unfile_buffer(jh); | 258 | __jbd2_journal_unfile_buffer(jh); |
255 | jbd_unlock_bh_state(bh); | 259 | jbd_unlock_bh_state(bh); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index c60f378b0f76..44fc32bfd7f1 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/suspend.h> | 34 | #include <linux/freezer.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/poison.h> | 37 | #include <linux/poison.h> |
@@ -1641,7 +1641,7 @@ void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | |||
1641 | #define JBD_MAX_SLABS 5 | 1641 | #define JBD_MAX_SLABS 5 |
1642 | #define JBD_SLAB_INDEX(size) (size >> 11) | 1642 | #define JBD_SLAB_INDEX(size) (size >> 11) |
1643 | 1643 | ||
1644 | static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; | 1644 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; |
1645 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | 1645 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { |
1646 | "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" | 1646 | "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" |
1647 | }; | 1647 | }; |
@@ -1704,7 +1704,7 @@ void jbd2_slab_free(void *ptr, size_t size) | |||
1704 | /* | 1704 | /* |
1705 | * Journal_head storage management | 1705 | * Journal_head storage management |
1706 | */ | 1706 | */ |
1707 | static kmem_cache_t *jbd2_journal_head_cache; | 1707 | static struct kmem_cache *jbd2_journal_head_cache; |
1708 | #ifdef CONFIG_JBD_DEBUG | 1708 | #ifdef CONFIG_JBD_DEBUG |
1709 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); | 1709 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
1710 | #endif | 1710 | #endif |
@@ -2007,7 +2007,7 @@ static void __exit jbd2_remove_jbd_proc_entry(void) | |||
2007 | 2007 | ||
2008 | #endif | 2008 | #endif |
2009 | 2009 | ||
2010 | kmem_cache_t *jbd2_handle_cache; | 2010 | struct kmem_cache *jbd2_handle_cache; |
2011 | 2011 | ||
2012 | static int __init journal_init_handle_cache(void) | 2012 | static int __init journal_init_handle_cache(void) |
2013 | { | 2013 | { |
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 380d19917f37..f506646ad0ff 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -70,8 +70,8 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | static kmem_cache_t *jbd2_revoke_record_cache; | 73 | static struct kmem_cache *jbd2_revoke_record_cache; |
74 | static kmem_cache_t *jbd2_revoke_table_cache; | 74 | static struct kmem_cache *jbd2_revoke_table_cache; |
75 | 75 | ||
76 | /* Each revoke record represents one single revoked block. During | 76 | /* Each revoke record represents one single revoked block. During |
77 | journal replay, this involves recording the transaction ID of the | 77 | journal replay, this involves recording the transaction ID of the |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index c051a94c8a97..3a8700153cb0 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | 29 | ||
30 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); | ||
31 | |||
30 | /* | 32 | /* |
31 | * jbd2_get_transaction: obtain a new transaction_t object. | 33 | * jbd2_get_transaction: obtain a new transaction_t object. |
32 | * | 34 | * |
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 3f7899ea4cba..43baa1afa021 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c | |||
@@ -61,8 +61,8 @@ static const struct file_operations jffs_dir_operations; | |||
61 | static struct inode_operations jffs_dir_inode_operations; | 61 | static struct inode_operations jffs_dir_inode_operations; |
62 | static const struct address_space_operations jffs_address_operations; | 62 | static const struct address_space_operations jffs_address_operations; |
63 | 63 | ||
64 | kmem_cache_t *node_cache = NULL; | 64 | struct kmem_cache *node_cache = NULL; |
65 | kmem_cache_t *fm_cache = NULL; | 65 | struct kmem_cache *fm_cache = NULL; |
66 | 66 | ||
67 | /* Called by the VFS at mount time to initialize the whole file system. */ | 67 | /* Called by the VFS at mount time to initialize the whole file system. */ |
68 | static int jffs_fill_super(struct super_block *sb, void *data, int silent) | 68 | static int jffs_fill_super(struct super_block *sb, void *data, int silent) |
@@ -566,7 +566,7 @@ static int | |||
566 | jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 566 | jffs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
567 | { | 567 | { |
568 | struct jffs_file *f; | 568 | struct jffs_file *f; |
569 | struct dentry *dentry = filp->f_dentry; | 569 | struct dentry *dentry = filp->f_path.dentry; |
570 | struct inode *inode = dentry->d_inode; | 570 | struct inode *inode = dentry->d_inode; |
571 | struct jffs_control *c = (struct jffs_control *)inode->i_sb->s_fs_info; | 571 | struct jffs_control *c = (struct jffs_control *)inode->i_sb->s_fs_info; |
572 | int j; | 572 | int j; |
@@ -818,7 +818,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
818 | 818 | ||
819 | D1({ | 819 | D1({ |
820 | int len = dentry->d_name.len; | 820 | int len = dentry->d_name.len; |
821 | char *_name = (char *) kmalloc(len + 1, GFP_KERNEL); | 821 | char *_name = kmalloc(len + 1, GFP_KERNEL); |
822 | memcpy(_name, dentry->d_name.name, len); | 822 | memcpy(_name, dentry->d_name.name, len); |
823 | _name[len] = '\0'; | 823 | _name[len] = '\0'; |
824 | printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", " | 824 | printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", " |
@@ -964,7 +964,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type) | |||
964 | D1({ | 964 | D1({ |
965 | int len = dentry->d_name.len; | 965 | int len = dentry->d_name.len; |
966 | const char *name = dentry->d_name.name; | 966 | const char *name = dentry->d_name.name; |
967 | char *_name = (char *) kmalloc(len + 1, GFP_KERNEL); | 967 | char *_name = kmalloc(len + 1, GFP_KERNEL); |
968 | memcpy(_name, name, len); | 968 | memcpy(_name, name, len); |
969 | _name[len] = '\0'; | 969 | _name[len] = '\0'; |
970 | printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino); | 970 | printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino); |
@@ -1372,7 +1372,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count, | |||
1372 | struct jffs_control *c; | 1372 | struct jffs_control *c; |
1373 | struct jffs_file *f; | 1373 | struct jffs_file *f; |
1374 | struct jffs_node *node; | 1374 | struct jffs_node *node; |
1375 | struct dentry *dentry = filp->f_dentry; | 1375 | struct dentry *dentry = filp->f_path.dentry; |
1376 | struct inode *inode = dentry->d_inode; | 1376 | struct inode *inode = dentry->d_inode; |
1377 | int recoverable = 0; | 1377 | int recoverable = 0; |
1378 | size_t written = 0; | 1378 | size_t written = 0; |
@@ -1380,7 +1380,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count, | |||
1380 | loff_t pos = *ppos; | 1380 | loff_t pos = *ppos; |
1381 | int err; | 1381 | int err; |
1382 | 1382 | ||
1383 | inode = filp->f_dentry->d_inode; | 1383 | inode = filp->f_path.dentry->d_inode; |
1384 | 1384 | ||
1385 | D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), " | 1385 | D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), " |
1386 | "filp: 0x%p, buf: 0x%p, count: %d\n", | 1386 | "filp: 0x%p, buf: 0x%p, count: %d\n", |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 4a543e114970..6dd18911b44c 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/smp_lock.h> | 66 | #include <linux/smp_lock.h> |
67 | #include <linux/time.h> | 67 | #include <linux/time.h> |
68 | #include <linux/ctype.h> | 68 | #include <linux/ctype.h> |
69 | #include <linux/freezer.h> | ||
69 | 70 | ||
70 | #include "intrep.h" | 71 | #include "intrep.h" |
71 | #include "jffs_fm.h" | 72 | #include "jffs_fm.h" |
@@ -435,7 +436,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result) | |||
435 | int i, length; | 436 | int i, length; |
436 | 437 | ||
437 | /* Allocate read buffer */ | 438 | /* Allocate read buffer */ |
438 | read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL); | 439 | read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL); |
439 | if (!read_buf) { | 440 | if (!read_buf) { |
440 | printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n"); | 441 | printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n"); |
441 | return -ENOMEM; | 442 | return -ENOMEM; |
@@ -591,7 +592,7 @@ jffs_add_virtual_root(struct jffs_control *c) | |||
591 | D2(printk("jffs_add_virtual_root(): " | 592 | D2(printk("jffs_add_virtual_root(): " |
592 | "Creating a virtual root directory.\n")); | 593 | "Creating a virtual root directory.\n")); |
593 | 594 | ||
594 | if (!(root = kmalloc(sizeof(struct jffs_file), GFP_KERNEL))) { | 595 | if (!(root = kzalloc(sizeof(struct jffs_file), GFP_KERNEL))) { |
595 | return -ENOMEM; | 596 | return -ENOMEM; |
596 | } | 597 | } |
597 | no_jffs_file++; | 598 | no_jffs_file++; |
@@ -603,7 +604,6 @@ jffs_add_virtual_root(struct jffs_control *c) | |||
603 | DJM(no_jffs_node++); | 604 | DJM(no_jffs_node++); |
604 | memset(node, 0, sizeof(struct jffs_node)); | 605 | memset(node, 0, sizeof(struct jffs_node)); |
605 | node->ino = JFFS_MIN_INO; | 606 | node->ino = JFFS_MIN_INO; |
606 | memset(root, 0, sizeof(struct jffs_file)); | ||
607 | root->ino = JFFS_MIN_INO; | 607 | root->ino = JFFS_MIN_INO; |
608 | root->mode = S_IFDIR | S_IRWXU | S_IRGRP | 608 | root->mode = S_IFDIR | S_IRWXU | S_IRGRP |
609 | | S_IXGRP | S_IROTH | S_IXOTH; | 609 | | S_IXGRP | S_IROTH | S_IXOTH; |
@@ -744,11 +744,11 @@ static int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){ | |||
744 | 744 | ||
745 | 745 | ||
746 | /* Allocate read buffers */ | 746 | /* Allocate read buffers */ |
747 | read_buf1 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL); | 747 | read_buf1 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL); |
748 | if (!read_buf1) | 748 | if (!read_buf1) |
749 | return -ENOMEM; | 749 | return -ENOMEM; |
750 | 750 | ||
751 | read_buf2 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL); | 751 | read_buf2 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL); |
752 | if (!read_buf2) { | 752 | if (!read_buf2) { |
753 | kfree(read_buf1); | 753 | kfree(read_buf1); |
754 | return -ENOMEM; | 754 | return -ENOMEM; |
@@ -876,7 +876,7 @@ jffs_scan_flash(struct jffs_control *c) | |||
876 | } | 876 | } |
877 | 877 | ||
878 | /* Allocate read buffer */ | 878 | /* Allocate read buffer */ |
879 | read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL); | 879 | read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL); |
880 | if (!read_buf) { | 880 | if (!read_buf) { |
881 | flash_safe_release(fmc->mtd); | 881 | flash_safe_release(fmc->mtd); |
882 | return -ENOMEM; | 882 | return -ENOMEM; |
@@ -1463,7 +1463,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f, | |||
1463 | kfree(f->name); | 1463 | kfree(f->name); |
1464 | DJM(no_name--); | 1464 | DJM(no_name--); |
1465 | } | 1465 | } |
1466 | if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1, | 1466 | if (!(f->name = kmalloc(raw_inode->nsize + 1, |
1467 | GFP_KERNEL))) { | 1467 | GFP_KERNEL))) { |
1468 | return -ENOMEM; | 1468 | return -ENOMEM; |
1469 | } | 1469 | } |
@@ -1737,7 +1737,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len) | |||
1737 | printk("jffs_find_child(): Found \"%s\".\n", f->name); | 1737 | printk("jffs_find_child(): Found \"%s\".\n", f->name); |
1738 | } | 1738 | } |
1739 | else { | 1739 | else { |
1740 | char *copy = (char *) kmalloc(len + 1, GFP_KERNEL); | 1740 | char *copy = kmalloc(len + 1, GFP_KERNEL); |
1741 | if (copy) { | 1741 | if (copy) { |
1742 | memcpy(copy, name, len); | 1742 | memcpy(copy, name, len); |
1743 | copy[len] = '\0'; | 1743 | copy[len] = '\0'; |
@@ -2627,7 +2627,7 @@ jffs_print_tree(struct jffs_file *first_file, int indent) | |||
2627 | return; | 2627 | return; |
2628 | } | 2628 | } |
2629 | 2629 | ||
2630 | if (!(space = (char *) kmalloc(indent + 1, GFP_KERNEL))) { | 2630 | if (!(space = kmalloc(indent + 1, GFP_KERNEL))) { |
2631 | printk("jffs_print_tree(): Out of memory!\n"); | 2631 | printk("jffs_print_tree(): Out of memory!\n"); |
2632 | return; | 2632 | return; |
2633 | } | 2633 | } |
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c index 6aab317f56e0..5a95fbdd6fdb 100644 --- a/fs/jffs/jffs_fm.c +++ b/fs/jffs/jffs_fm.c | |||
@@ -30,8 +30,8 @@ static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset); | |||
30 | static struct jffs_fm *jffs_alloc_fm(void); | 30 | static struct jffs_fm *jffs_alloc_fm(void); |
31 | static void jffs_free_fm(struct jffs_fm *n); | 31 | static void jffs_free_fm(struct jffs_fm *n); |
32 | 32 | ||
33 | extern kmem_cache_t *fm_cache; | 33 | extern struct kmem_cache *fm_cache; |
34 | extern kmem_cache_t *node_cache; | 34 | extern struct kmem_cache *node_cache; |
35 | 35 | ||
36 | #if CONFIG_JFFS_FS_VERBOSE > 0 | 36 | #if CONFIG_JFFS_FS_VERBOSE > 0 |
37 | void | 37 | void |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 0ae3cd10702c..73f0d60f73a5 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/sched.h> | ||
14 | #include <linux/time.h> | 15 | #include <linux/time.h> |
15 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
16 | #include <linux/jffs2.h> | 17 | #include <linux/jffs2.h> |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index ff2a872e80e7..6eb3daebd563 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
17 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/freezer.h> | ||
19 | #include "nodelist.h" | 20 | #include "nodelist.h" |
20 | 21 | ||
21 | 22 | ||
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 9def6adf4a5d..da6034d50718 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -123,11 +123,11 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
123 | { | 123 | { |
124 | struct jffs2_inode_info *f; | 124 | struct jffs2_inode_info *f; |
125 | struct jffs2_sb_info *c; | 125 | struct jffs2_sb_info *c; |
126 | struct inode *inode = filp->f_dentry->d_inode; | 126 | struct inode *inode = filp->f_path.dentry->d_inode; |
127 | struct jffs2_full_dirent *fd; | 127 | struct jffs2_full_dirent *fd; |
128 | unsigned long offset, curofs; | 128 | unsigned long offset, curofs; |
129 | 129 | ||
130 | D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_dentry->d_inode->i_ino)); | 130 | D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_path.dentry->d_inode->i_ino)); |
131 | 131 | ||
132 | f = JFFS2_INODE_INFO(inode); | 132 | f = JFFS2_INODE_INFO(inode); |
133 | c = JFFS2_SB_INFO(inode->i_sb); | 133 | c = JFFS2_SB_INFO(inode->i_sb); |
@@ -141,7 +141,7 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
141 | offset++; | 141 | offset++; |
142 | } | 142 | } |
143 | if (offset == 1) { | 143 | if (offset == 1) { |
144 | unsigned long pino = parent_ino(filp->f_dentry); | 144 | unsigned long pino = parent_ino(filp->f_path.dentry); |
145 | D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino)); | 145 | D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino)); |
146 | if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0) | 146 | if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0) |
147 | goto out; | 147 | goto out; |
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 33f291005012..83f9881ec4cc 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
@@ -19,16 +19,16 @@ | |||
19 | 19 | ||
20 | /* These are initialised to NULL in the kernel startup code. | 20 | /* These are initialised to NULL in the kernel startup code. |
21 | If you're porting to other operating systems, beware */ | 21 | If you're porting to other operating systems, beware */ |
22 | static kmem_cache_t *full_dnode_slab; | 22 | static struct kmem_cache *full_dnode_slab; |
23 | static kmem_cache_t *raw_dirent_slab; | 23 | static struct kmem_cache *raw_dirent_slab; |
24 | static kmem_cache_t *raw_inode_slab; | 24 | static struct kmem_cache *raw_inode_slab; |
25 | static kmem_cache_t *tmp_dnode_info_slab; | 25 | static struct kmem_cache *tmp_dnode_info_slab; |
26 | static kmem_cache_t *raw_node_ref_slab; | 26 | static struct kmem_cache *raw_node_ref_slab; |
27 | static kmem_cache_t *node_frag_slab; | 27 | static struct kmem_cache *node_frag_slab; |
28 | static kmem_cache_t *inode_cache_slab; | 28 | static struct kmem_cache *inode_cache_slab; |
29 | #ifdef CONFIG_JFFS2_FS_XATTR | 29 | #ifdef CONFIG_JFFS2_FS_XATTR |
30 | static kmem_cache_t *xattr_datum_cache; | 30 | static struct kmem_cache *xattr_datum_cache; |
31 | static kmem_cache_t *xattr_ref_cache; | 31 | static struct kmem_cache *xattr_ref_cache; |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | int __init jffs2_create_slab_caches(void) | 34 | int __init jffs2_create_slab_caches(void) |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 590f60a897c1..08a0e6c49e61 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -29,12 +29,12 @@ | |||
29 | 29 | ||
30 | static void jffs2_put_super(struct super_block *); | 30 | static void jffs2_put_super(struct super_block *); |
31 | 31 | ||
32 | static kmem_cache_t *jffs2_inode_cachep; | 32 | static struct kmem_cache *jffs2_inode_cachep; |
33 | 33 | ||
34 | static struct inode *jffs2_alloc_inode(struct super_block *sb) | 34 | static struct inode *jffs2_alloc_inode(struct super_block *sb) |
35 | { | 35 | { |
36 | struct jffs2_inode_info *ei; | 36 | struct jffs2_inode_info *ei; |
37 | ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL); | 37 | ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); |
38 | if (!ei) | 38 | if (!ei) |
39 | return NULL; | 39 | return NULL; |
40 | return &ei->vfs_inode; | 40 | return &ei->vfs_inode; |
@@ -45,7 +45,7 @@ static void jffs2_destroy_inode(struct inode *inode) | |||
45 | kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); | 45 | kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 48 | static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
49 | { | 49 | { |
50 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; | 50 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; |
51 | 51 | ||
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index dcb18e9a646e..9c99859f5edd 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/crc32.h> | 19 | #include <linux/crc32.h> |
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | #include "nodelist.h" | 24 | #include "nodelist.h" |
24 | 25 | ||
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 37db52488262..ed814b1ff4d9 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/sched.h> | ||
12 | #include <asm/current.h> | 13 | #include <asm/current.h> |
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | 15 | ||
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index ecb2216d881c..6d62f3222892 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c | |||
@@ -3009,7 +3009,7 @@ static inline struct jfs_dirent *next_jfs_dirent(struct jfs_dirent *dirent) | |||
3009 | */ | 3009 | */ |
3010 | int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 3010 | int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
3011 | { | 3011 | { |
3012 | struct inode *ip = filp->f_dentry->d_inode; | 3012 | struct inode *ip = filp->f_path.dentry->d_inode; |
3013 | struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab; | 3013 | struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab; |
3014 | int rc = 0; | 3014 | int rc = 0; |
3015 | loff_t dtpos; /* legacy OS/2 style position */ | 3015 | loff_t dtpos; /* legacy OS/2 style position */ |
@@ -3777,12 +3777,12 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, | |||
3777 | struct component_name lkey; | 3777 | struct component_name lkey; |
3778 | struct component_name rkey; | 3778 | struct component_name rkey; |
3779 | 3779 | ||
3780 | lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), | 3780 | lkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), |
3781 | GFP_KERNEL); | 3781 | GFP_KERNEL); |
3782 | if (lkey.name == NULL) | 3782 | if (lkey.name == NULL) |
3783 | return -ENOMEM; | 3783 | return -ENOMEM; |
3784 | 3784 | ||
3785 | rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), | 3785 | rkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), |
3786 | GFP_KERNEL); | 3786 | GFP_KERNEL); |
3787 | if (rkey.name == NULL) { | 3787 | if (rkey.name == NULL) { |
3788 | kfree(lkey.name); | 3788 | kfree(lkey.name); |
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h index 9901928668cf..38f70ac03bec 100644 --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h | |||
@@ -29,31 +29,21 @@ | |||
29 | /* | 29 | /* |
30 | * file system option (superblock flag) | 30 | * file system option (superblock flag) |
31 | */ | 31 | */ |
32 | /* mount time flag to disable journaling to disk */ | 32 | |
33 | #define JFS_NOINTEGRITY 0x00000010 | 33 | /* directory option */ |
34 | #define JFS_UNICODE 0x00000001 /* unicode name */ | ||
34 | 35 | ||
35 | /* mount time flags for error handling */ | 36 | /* mount time flags for error handling */ |
36 | #define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */ | 37 | #define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */ |
37 | #define JFS_ERR_CONTINUE 0x00000004 /* continue */ | 38 | #define JFS_ERR_CONTINUE 0x00000004 /* continue */ |
38 | #define JFS_ERR_PANIC 0x00000008 /* panic */ | 39 | #define JFS_ERR_PANIC 0x00000008 /* panic */ |
39 | 40 | ||
41 | /* Quota support */ | ||
40 | #define JFS_USRQUOTA 0x00000010 | 42 | #define JFS_USRQUOTA 0x00000010 |
41 | #define JFS_GRPQUOTA 0x00000020 | 43 | #define JFS_GRPQUOTA 0x00000020 |
42 | 44 | ||
43 | /* platform option (conditional compilation) */ | 45 | /* mount time flag to disable journaling to disk */ |
44 | #define JFS_AIX 0x80000000 /* AIX support */ | 46 | #define JFS_NOINTEGRITY 0x00000040 |
45 | /* POSIX name/directory support */ | ||
46 | |||
47 | #define JFS_OS2 0x40000000 /* OS/2 support */ | ||
48 | /* case-insensitive name/directory support */ | ||
49 | |||
50 | #define JFS_DFS 0x20000000 /* DCE DFS LFS support */ | ||
51 | |||
52 | #define JFS_LINUX 0x10000000 /* Linux support */ | ||
53 | /* case-sensitive name/directory support */ | ||
54 | |||
55 | /* directory option */ | ||
56 | #define JFS_UNICODE 0x00000001 /* unicode name */ | ||
57 | 47 | ||
58 | /* commit option */ | 48 | /* commit option */ |
59 | #define JFS_COMMIT 0x00000f00 /* commit option mask */ | 49 | #define JFS_COMMIT 0x00000f00 /* commit option mask */ |
@@ -61,6 +51,7 @@ | |||
61 | #define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */ | 51 | #define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */ |
62 | #define JFS_TMPFS 0x00000400 /* temporary file system - | 52 | #define JFS_TMPFS 0x00000400 /* temporary file system - |
63 | * do not log/commit: | 53 | * do not log/commit: |
54 | * Never implemented | ||
64 | */ | 55 | */ |
65 | 56 | ||
66 | /* log logical volume option */ | 57 | /* log logical volume option */ |
@@ -74,16 +65,25 @@ | |||
74 | #define JFS_SPARSE 0x00020000 /* sparse regular file */ | 65 | #define JFS_SPARSE 0x00020000 /* sparse regular file */ |
75 | 66 | ||
76 | /* DASD Limits F226941 */ | 67 | /* DASD Limits F226941 */ |
77 | #define JFS_DASD_ENABLED 0x00040000 /* DASD limits enabled */ | 68 | #define JFS_DASD_ENABLED 0x00040000 /* DASD limits enabled */ |
78 | #define JFS_DASD_PRIME 0x00080000 /* Prime DASD usage on boot */ | 69 | #define JFS_DASD_PRIME 0x00080000 /* Prime DASD usage on boot */ |
79 | 70 | ||
80 | /* big endian flag */ | 71 | /* big endian flag */ |
81 | #define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ | 72 | #define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ |
82 | 73 | ||
83 | /* Directory index */ | 74 | /* Directory index */ |
84 | #define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ | 75 | #define JFS_DIR_INDEX 0x00200000 /* Persistent index for */ |
85 | /* directory entries */ | ||
86 | 76 | ||
77 | /* platform options */ | ||
78 | #define JFS_LINUX 0x10000000 /* Linux support */ | ||
79 | #define JFS_DFS 0x20000000 /* DCE DFS LFS support */ | ||
80 | /* Never implemented */ | ||
81 | |||
82 | #define JFS_OS2 0x40000000 /* OS/2 support */ | ||
83 | /* case-insensitive name/directory support */ | ||
84 | |||
85 | #define JFS_AIX 0x80000000 /* AIX support */ | ||
86 | /* POSIX name/directory support - Never implemented*/ | ||
87 | 87 | ||
88 | /* | 88 | /* |
89 | * buffer cache configuration | 89 | * buffer cache configuration |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index ee9b473b7b80..53f63b47a6d3 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -120,7 +120,7 @@ int diMount(struct inode *ipimap) | |||
120 | * allocate/initialize the in-memory inode map control structure | 120 | * allocate/initialize the in-memory inode map control structure |
121 | */ | 121 | */ |
122 | /* allocate the in-memory inode map control structure. */ | 122 | /* allocate the in-memory inode map control structure. */ |
123 | imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL); | 123 | imap = kmalloc(sizeof(struct inomap), GFP_KERNEL); |
124 | if (imap == NULL) { | 124 | if (imap == NULL) { |
125 | jfs_err("diMount: kmalloc returned NULL!"); | 125 | jfs_err("diMount: kmalloc returned NULL!"); |
126 | return -ENOMEM; | 126 | return -ENOMEM; |
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index b89c9aba0466..5065baa530b6 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -67,7 +67,7 @@ | |||
67 | #include <linux/kthread.h> | 67 | #include <linux/kthread.h> |
68 | #include <linux/buffer_head.h> /* for sync_blockdev() */ | 68 | #include <linux/buffer_head.h> /* for sync_blockdev() */ |
69 | #include <linux/bio.h> | 69 | #include <linux/bio.h> |
70 | #include <linux/suspend.h> | 70 | #include <linux/freezer.h> |
71 | #include <linux/delay.h> | 71 | #include <linux/delay.h> |
72 | #include <linux/mutex.h> | 72 | #include <linux/mutex.h> |
73 | #include "jfs_incore.h" | 73 | #include "jfs_incore.h" |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 0cccd1c39d75..ceaf03b94935 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -74,7 +74,7 @@ static inline void lock_metapage(struct metapage *mp) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | #define METAPOOL_MIN_PAGES 32 | 76 | #define METAPOOL_MIN_PAGES 32 |
77 | static kmem_cache_t *metapage_cache; | 77 | static struct kmem_cache *metapage_cache; |
78 | static mempool_t *metapage_mempool; | 78 | static mempool_t *metapage_mempool; |
79 | 79 | ||
80 | #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) | 80 | #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) |
@@ -180,7 +180,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp) | |||
180 | 180 | ||
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 183 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
184 | { | 184 | { |
185 | struct metapage *mp = (struct metapage *)foo; | 185 | struct metapage *mp = (struct metapage *)foo; |
186 | 186 | ||
@@ -764,22 +764,9 @@ void release_metapage(struct metapage * mp) | |||
764 | } else if (mp->lsn) /* discard_metapage doesn't remove it */ | 764 | } else if (mp->lsn) /* discard_metapage doesn't remove it */ |
765 | remove_from_logsync(mp); | 765 | remove_from_logsync(mp); |
766 | 766 | ||
767 | #if MPS_PER_PAGE == 1 | ||
768 | /* | ||
769 | * If we know this is the only thing in the page, we can throw | ||
770 | * the page out of the page cache. If pages are larger, we | ||
771 | * don't want to do this. | ||
772 | */ | ||
773 | |||
774 | /* Retest mp->count since we may have released page lock */ | ||
775 | if (test_bit(META_discard, &mp->flag) && !mp->count) { | ||
776 | clear_page_dirty(page); | ||
777 | ClearPageUptodate(page); | ||
778 | } | ||
779 | #else | ||
780 | /* Try to keep metapages from using up too much memory */ | 767 | /* Try to keep metapages from using up too much memory */ |
781 | drop_metapage(page, mp); | 768 | drop_metapage(page, mp); |
782 | #endif | 769 | |
783 | unlock_page(page); | 770 | unlock_page(page); |
784 | page_cache_release(page); | 771 | page_cache_release(page); |
785 | } | 772 | } |
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 81f6f04af192..d558e51b0df8 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
47 | #include <linux/smp_lock.h> | 47 | #include <linux/smp_lock.h> |
48 | #include <linux/completion.h> | 48 | #include <linux/completion.h> |
49 | #include <linux/suspend.h> | 49 | #include <linux/freezer.h> |
50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
51 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
52 | #include <linux/kthread.h> | 52 | #include <linux/kthread.h> |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 9c1c6e0e633d..846ac8f34513 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -44,7 +44,7 @@ MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); | |||
44 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); | 44 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); |
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static kmem_cache_t * jfs_inode_cachep; | 47 | static struct kmem_cache * jfs_inode_cachep; |
48 | 48 | ||
49 | static struct super_operations jfs_super_operations; | 49 | static struct super_operations jfs_super_operations; |
50 | static struct export_operations jfs_export_operations; | 50 | static struct export_operations jfs_export_operations; |
@@ -93,7 +93,7 @@ void jfs_error(struct super_block *sb, const char * function, ...) | |||
93 | va_list args; | 93 | va_list args; |
94 | 94 | ||
95 | va_start(args, function); | 95 | va_start(args, function); |
96 | vsprintf(error_buf, function, args); | 96 | vsnprintf(error_buf, sizeof(error_buf), function, args); |
97 | va_end(args); | 97 | va_end(args); |
98 | 98 | ||
99 | printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); | 99 | printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); |
@@ -748,7 +748,7 @@ static struct file_system_type jfs_fs_type = { | |||
748 | .fs_flags = FS_REQUIRES_DEV, | 748 | .fs_flags = FS_REQUIRES_DEV, |
749 | }; | 749 | }; |
750 | 750 | ||
751 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 751 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
752 | { | 752 | { |
753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; | 753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; |
754 | 754 | ||
diff --git a/fs/libfs.c b/fs/libfs.c index bd08e0e64a8c..503898d5c4a7 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -63,7 +63,7 @@ int dcache_dir_open(struct inode *inode, struct file *file) | |||
63 | { | 63 | { |
64 | static struct qstr cursor_name = {.len = 1, .name = "."}; | 64 | static struct qstr cursor_name = {.len = 1, .name = "."}; |
65 | 65 | ||
66 | file->private_data = d_alloc(file->f_dentry, &cursor_name); | 66 | file->private_data = d_alloc(file->f_path.dentry, &cursor_name); |
67 | 67 | ||
68 | return file->private_data ? 0 : -ENOMEM; | 68 | return file->private_data ? 0 : -ENOMEM; |
69 | } | 69 | } |
@@ -76,7 +76,7 @@ int dcache_dir_close(struct inode *inode, struct file *file) | |||
76 | 76 | ||
77 | loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | 77 | loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) |
78 | { | 78 | { |
79 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | 79 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); |
80 | switch (origin) { | 80 | switch (origin) { |
81 | case 1: | 81 | case 1: |
82 | offset += file->f_pos; | 82 | offset += file->f_pos; |
@@ -84,7 +84,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
84 | if (offset >= 0) | 84 | if (offset >= 0) |
85 | break; | 85 | break; |
86 | default: | 86 | default: |
87 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 87 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
88 | return -EINVAL; | 88 | return -EINVAL; |
89 | } | 89 | } |
90 | if (offset != file->f_pos) { | 90 | if (offset != file->f_pos) { |
@@ -96,8 +96,8 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
96 | 96 | ||
97 | spin_lock(&dcache_lock); | 97 | spin_lock(&dcache_lock); |
98 | list_del(&cursor->d_u.d_child); | 98 | list_del(&cursor->d_u.d_child); |
99 | p = file->f_dentry->d_subdirs.next; | 99 | p = file->f_path.dentry->d_subdirs.next; |
100 | while (n && p != &file->f_dentry->d_subdirs) { | 100 | while (n && p != &file->f_path.dentry->d_subdirs) { |
101 | struct dentry *next; | 101 | struct dentry *next; |
102 | next = list_entry(p, struct dentry, d_u.d_child); | 102 | next = list_entry(p, struct dentry, d_u.d_child); |
103 | if (!d_unhashed(next) && next->d_inode) | 103 | if (!d_unhashed(next) && next->d_inode) |
@@ -108,7 +108,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
108 | spin_unlock(&dcache_lock); | 108 | spin_unlock(&dcache_lock); |
109 | } | 109 | } |
110 | } | 110 | } |
111 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 111 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
112 | return offset; | 112 | return offset; |
113 | } | 113 | } |
114 | 114 | ||
@@ -126,7 +126,7 @@ static inline unsigned char dt_type(struct inode *inode) | |||
126 | 126 | ||
127 | int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) | 127 | int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) |
128 | { | 128 | { |
129 | struct dentry *dentry = filp->f_dentry; | 129 | struct dentry *dentry = filp->f_path.dentry; |
130 | struct dentry *cursor = filp->private_data; | 130 | struct dentry *cursor = filp->private_data; |
131 | struct list_head *p, *q = &cursor->d_u.d_child; | 131 | struct list_head *p, *q = &cursor->d_u.d_child; |
132 | ino_t ino; | 132 | ino_t ino; |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index b85a0ad2cfb6..062707745162 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -36,7 +36,7 @@ struct nlm_wait { | |||
36 | struct nlm_host * b_host; | 36 | struct nlm_host * b_host; |
37 | struct file_lock * b_lock; /* local file lock */ | 37 | struct file_lock * b_lock; /* local file lock */ |
38 | unsigned short b_reclaim; /* got to reclaim lock */ | 38 | unsigned short b_reclaim; /* got to reclaim lock */ |
39 | u32 b_status; /* grant callback status */ | 39 | __be32 b_status; /* grant callback status */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static LIST_HEAD(nlm_blocked); | 42 | static LIST_HEAD(nlm_blocked); |
@@ -53,7 +53,7 @@ struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock * | |||
53 | block->b_host = host; | 53 | block->b_host = host; |
54 | block->b_lock = fl; | 54 | block->b_lock = fl; |
55 | init_waitqueue_head(&block->b_wait); | 55 | init_waitqueue_head(&block->b_wait); |
56 | block->b_status = NLM_LCK_BLOCKED; | 56 | block->b_status = nlm_lck_blocked; |
57 | list_add(&block->b_list, &nlm_blocked); | 57 | list_add(&block->b_list, &nlm_blocked); |
58 | } | 58 | } |
59 | return block; | 59 | return block; |
@@ -89,7 +89,7 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
89 | * nlmclnt_lock for an explanation. | 89 | * nlmclnt_lock for an explanation. |
90 | */ | 90 | */ |
91 | ret = wait_event_interruptible_timeout(block->b_wait, | 91 | ret = wait_event_interruptible_timeout(block->b_wait, |
92 | block->b_status != NLM_LCK_BLOCKED, | 92 | block->b_status != nlm_lck_blocked, |
93 | timeout); | 93 | timeout); |
94 | if (ret < 0) | 94 | if (ret < 0) |
95 | return -ERESTARTSYS; | 95 | return -ERESTARTSYS; |
@@ -126,12 +126,12 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock | |||
126 | continue; | 126 | continue; |
127 | if (!nlm_cmp_addr(&block->b_host->h_addr, addr)) | 127 | if (!nlm_cmp_addr(&block->b_host->h_addr, addr)) |
128 | continue; | 128 | continue; |
129 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode) ,fh) != 0) | 129 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
130 | continue; | 130 | continue; |
131 | /* Alright, we found a lock. Set the return status | 131 | /* Alright, we found a lock. Set the return status |
132 | * and wake up the caller | 132 | * and wake up the caller |
133 | */ | 133 | */ |
134 | block->b_status = NLM_LCK_GRANTED; | 134 | block->b_status = nlm_granted; |
135 | wake_up(&block->b_wait); | 135 | wake_up(&block->b_wait); |
136 | res = nlm_granted; | 136 | res = nlm_granted; |
137 | } | 137 | } |
@@ -211,7 +211,7 @@ restart: | |||
211 | /* Now, wake up all processes that sleep on a blocked lock */ | 211 | /* Now, wake up all processes that sleep on a blocked lock */ |
212 | list_for_each_entry(block, &nlm_blocked, b_list) { | 212 | list_for_each_entry(block, &nlm_blocked, b_list) { |
213 | if (block->b_host == host) { | 213 | if (block->b_host == host) { |
214 | block->b_status = NLM_LCK_DENIED_GRACE_PERIOD; | 214 | block->b_status = nlm_lck_denied_grace_period; |
215 | wake_up(&block->b_wait); | 215 | wake_up(&block->b_wait); |
216 | } | 216 | } |
217 | } | 217 | } |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 3d84f600b633..0b4acc1c5e7d 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/nfs_fs.h> | 13 | #include <linux/nfs_fs.h> |
14 | #include <linux/utsname.h> | 14 | #include <linux/utsname.h> |
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/freezer.h> | ||
16 | #include <linux/sunrpc/clnt.h> | 17 | #include <linux/sunrpc/clnt.h> |
17 | #include <linux/sunrpc/svc.h> | 18 | #include <linux/sunrpc/svc.h> |
18 | #include <linux/lockd/lockd.h> | 19 | #include <linux/lockd/lockd.h> |
@@ -26,7 +27,7 @@ | |||
26 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); | 27 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); |
27 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); | 28 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); |
28 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); | 29 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); |
29 | static int nlm_stat_to_errno(u32 stat); | 30 | static int nlm_stat_to_errno(__be32 stat); |
30 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); | 31 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); |
31 | static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *); | 32 | static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *); |
32 | 33 | ||
@@ -128,7 +129,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) | |||
128 | 129 | ||
129 | nlmclnt_next_cookie(&argp->cookie); | 130 | nlmclnt_next_cookie(&argp->cookie); |
130 | argp->state = nsm_local_state; | 131 | argp->state = nsm_local_state; |
131 | memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh)); | 132 | memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh)); |
132 | lock->caller = utsname()->nodename; | 133 | lock->caller = utsname()->nodename; |
133 | lock->oh.data = req->a_owner; | 134 | lock->oh.data = req->a_owner; |
134 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", | 135 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", |
@@ -324,7 +325,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) | |||
324 | } | 325 | } |
325 | break; | 326 | break; |
326 | } else | 327 | } else |
327 | if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) { | 328 | if (resp->status == nlm_lck_denied_grace_period) { |
328 | dprintk("lockd: server in grace period\n"); | 329 | dprintk("lockd: server in grace period\n"); |
329 | if (argp->reclaim) { | 330 | if (argp->reclaim) { |
330 | printk(KERN_WARNING | 331 | printk(KERN_WARNING |
@@ -410,10 +411,10 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) | |||
410 | goto out; | 411 | goto out; |
411 | 412 | ||
412 | switch (req->a_res.status) { | 413 | switch (req->a_res.status) { |
413 | case NLM_LCK_GRANTED: | 414 | case nlm_granted: |
414 | fl->fl_type = F_UNLCK; | 415 | fl->fl_type = F_UNLCK; |
415 | break; | 416 | break; |
416 | case NLM_LCK_DENIED: | 417 | case nlm_lck_denied: |
417 | /* | 418 | /* |
418 | * Report the conflicting lock back to the application. | 419 | * Report the conflicting lock back to the application. |
419 | */ | 420 | */ |
@@ -523,9 +524,9 @@ again: | |||
523 | if (!req->a_args.block) | 524 | if (!req->a_args.block) |
524 | break; | 525 | break; |
525 | /* Did a reclaimer thread notify us of a server reboot? */ | 526 | /* Did a reclaimer thread notify us of a server reboot? */ |
526 | if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) | 527 | if (resp->status == nlm_lck_denied_grace_period) |
527 | continue; | 528 | continue; |
528 | if (resp->status != NLM_LCK_BLOCKED) | 529 | if (resp->status != nlm_lck_blocked) |
529 | break; | 530 | break; |
530 | /* Wait on an NLM blocking lock */ | 531 | /* Wait on an NLM blocking lock */ |
531 | status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); | 532 | status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); |
@@ -534,11 +535,11 @@ again: | |||
534 | */ | 535 | */ |
535 | if (status < 0) | 536 | if (status < 0) |
536 | goto out_unblock; | 537 | goto out_unblock; |
537 | if (resp->status != NLM_LCK_BLOCKED) | 538 | if (resp->status != nlm_lck_blocked) |
538 | break; | 539 | break; |
539 | } | 540 | } |
540 | 541 | ||
541 | if (resp->status == NLM_LCK_GRANTED) { | 542 | if (resp->status == nlm_granted) { |
542 | down_read(&host->h_rwsem); | 543 | down_read(&host->h_rwsem); |
543 | /* Check whether or not the server has rebooted */ | 544 | /* Check whether or not the server has rebooted */ |
544 | if (fl->fl_u.nfs_fl.state != host->h_state) { | 545 | if (fl->fl_u.nfs_fl.state != host->h_state) { |
@@ -555,7 +556,7 @@ again: | |||
555 | out_unblock: | 556 | out_unblock: |
556 | nlmclnt_finish_block(block); | 557 | nlmclnt_finish_block(block); |
557 | /* Cancel the blocked request if it is still pending */ | 558 | /* Cancel the blocked request if it is still pending */ |
558 | if (resp->status == NLM_LCK_BLOCKED) | 559 | if (resp->status == nlm_lck_blocked) |
559 | nlmclnt_cancel(host, req->a_args.block, fl); | 560 | nlmclnt_cancel(host, req->a_args.block, fl); |
560 | out: | 561 | out: |
561 | nlm_release_call(req); | 562 | nlm_release_call(req); |
@@ -584,12 +585,12 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl) | |||
584 | req->a_args.reclaim = 1; | 585 | req->a_args.reclaim = 1; |
585 | 586 | ||
586 | if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0 | 587 | if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0 |
587 | && req->a_res.status == NLM_LCK_GRANTED) | 588 | && req->a_res.status == nlm_granted) |
588 | return 0; | 589 | return 0; |
589 | 590 | ||
590 | printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d " | 591 | printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d " |
591 | "(errno %d, status %d)\n", fl->fl_pid, | 592 | "(errno %d, status %d)\n", fl->fl_pid, |
592 | status, req->a_res.status); | 593 | status, ntohl(req->a_res.status)); |
593 | 594 | ||
594 | /* | 595 | /* |
595 | * FIXME: This is a serious failure. We can | 596 | * FIXME: This is a serious failure. We can |
@@ -636,10 +637,10 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
636 | if (status < 0) | 637 | if (status < 0) |
637 | goto out; | 638 | goto out; |
638 | 639 | ||
639 | if (resp->status == NLM_LCK_GRANTED) | 640 | if (resp->status == nlm_granted) |
640 | goto out; | 641 | goto out; |
641 | 642 | ||
642 | if (resp->status != NLM_LCK_DENIED_NOLOCKS) | 643 | if (resp->status != nlm_lck_denied_nolocks) |
643 | printk("lockd: unexpected unlock status: %d\n", resp->status); | 644 | printk("lockd: unexpected unlock status: %d\n", resp->status); |
644 | /* What to do now? I'm out of my depth... */ | 645 | /* What to do now? I'm out of my depth... */ |
645 | status = -ENOLCK; | 646 | status = -ENOLCK; |
@@ -651,7 +652,7 @@ out: | |||
651 | static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) | 652 | static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) |
652 | { | 653 | { |
653 | struct nlm_rqst *req = data; | 654 | struct nlm_rqst *req = data; |
654 | int status = req->a_res.status; | 655 | u32 status = ntohl(req->a_res.status); |
655 | 656 | ||
656 | if (RPC_ASSASSINATED(task)) | 657 | if (RPC_ASSASSINATED(task)) |
657 | goto die; | 658 | goto die; |
@@ -719,6 +720,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl | |||
719 | static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) | 720 | static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) |
720 | { | 721 | { |
721 | struct nlm_rqst *req = data; | 722 | struct nlm_rqst *req = data; |
723 | u32 status = ntohl(req->a_res.status); | ||
722 | 724 | ||
723 | if (RPC_ASSASSINATED(task)) | 725 | if (RPC_ASSASSINATED(task)) |
724 | goto die; | 726 | goto die; |
@@ -729,10 +731,10 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) | |||
729 | goto retry_cancel; | 731 | goto retry_cancel; |
730 | } | 732 | } |
731 | 733 | ||
732 | dprintk("lockd: cancel status %d (task %d)\n", | 734 | dprintk("lockd: cancel status %u (task %u)\n", |
733 | req->a_res.status, task->tk_pid); | 735 | status, task->tk_pid); |
734 | 736 | ||
735 | switch (req->a_res.status) { | 737 | switch (status) { |
736 | case NLM_LCK_GRANTED: | 738 | case NLM_LCK_GRANTED: |
737 | case NLM_LCK_DENIED_GRACE_PERIOD: | 739 | case NLM_LCK_DENIED_GRACE_PERIOD: |
738 | case NLM_LCK_DENIED: | 740 | case NLM_LCK_DENIED: |
@@ -743,7 +745,7 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) | |||
743 | goto retry_cancel; | 745 | goto retry_cancel; |
744 | default: | 746 | default: |
745 | printk(KERN_NOTICE "lockd: weird return %d for CANCEL call\n", | 747 | printk(KERN_NOTICE "lockd: weird return %d for CANCEL call\n", |
746 | req->a_res.status); | 748 | status); |
747 | } | 749 | } |
748 | 750 | ||
749 | die: | 751 | die: |
@@ -767,9 +769,9 @@ static const struct rpc_call_ops nlmclnt_cancel_ops = { | |||
767 | * Convert an NLM status code to a generic kernel errno | 769 | * Convert an NLM status code to a generic kernel errno |
768 | */ | 770 | */ |
769 | static int | 771 | static int |
770 | nlm_stat_to_errno(u32 status) | 772 | nlm_stat_to_errno(__be32 status) |
771 | { | 773 | { |
772 | switch(status) { | 774 | switch(ntohl(status)) { |
773 | case NLM_LCK_GRANTED: | 775 | case NLM_LCK_GRANTED: |
774 | return 0; | 776 | return 0; |
775 | case NLM_LCK_DENIED: | 777 | case NLM_LCK_DENIED: |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index fb24a9730345..3d4610c2a266 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -36,34 +36,14 @@ static DEFINE_MUTEX(nlm_host_mutex); | |||
36 | static void nlm_gc_hosts(void); | 36 | static void nlm_gc_hosts(void); |
37 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, | 37 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, |
38 | const char *, int, int); | 38 | const char *, int, int); |
39 | 39 | static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | |
40 | /* | 40 | const char *hostname, |
41 | * Find an NLM server handle in the cache. If there is none, create it. | 41 | int hostname_len); |
42 | */ | ||
43 | struct nlm_host * | ||
44 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | ||
45 | const char *hostname, int hostname_len) | ||
46 | { | ||
47 | return nlm_lookup_host(0, sin, proto, version, | ||
48 | hostname, hostname_len); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Find an NLM client handle in the cache. If there is none, create it. | ||
53 | */ | ||
54 | struct nlm_host * | ||
55 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | ||
56 | const char *hostname, int hostname_len) | ||
57 | { | ||
58 | return nlm_lookup_host(1, &rqstp->rq_addr, | ||
59 | rqstp->rq_prot, rqstp->rq_vers, | ||
60 | hostname, hostname_len); | ||
61 | } | ||
62 | 42 | ||
63 | /* | 43 | /* |
64 | * Common host lookup routine for server & client | 44 | * Common host lookup routine for server & client |
65 | */ | 45 | */ |
66 | struct nlm_host * | 46 | static struct nlm_host * |
67 | nlm_lookup_host(int server, const struct sockaddr_in *sin, | 47 | nlm_lookup_host(int server, const struct sockaddr_in *sin, |
68 | int proto, int version, | 48 | int proto, int version, |
69 | const char *hostname, | 49 | const char *hostname, |
@@ -195,6 +175,29 @@ nlm_destroy_host(struct nlm_host *host) | |||
195 | } | 175 | } |
196 | 176 | ||
197 | /* | 177 | /* |
178 | * Find an NLM server handle in the cache. If there is none, create it. | ||
179 | */ | ||
180 | struct nlm_host * | ||
181 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | ||
182 | const char *hostname, int hostname_len) | ||
183 | { | ||
184 | return nlm_lookup_host(0, sin, proto, version, | ||
185 | hostname, hostname_len); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Find an NLM client handle in the cache. If there is none, create it. | ||
190 | */ | ||
191 | struct nlm_host * | ||
192 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | ||
193 | const char *hostname, int hostname_len) | ||
194 | { | ||
195 | return nlm_lookup_host(1, &rqstp->rq_addr, | ||
196 | rqstp->rq_prot, rqstp->rq_vers, | ||
197 | hostname, hostname_len); | ||
198 | } | ||
199 | |||
200 | /* | ||
198 | * Create the NLM RPC client for an NLM peer | 201 | * Create the NLM RPC client for an NLM peer |
199 | */ | 202 | */ |
200 | struct rpc_clnt * | 203 | struct rpc_clnt * |
@@ -495,7 +498,7 @@ out: | |||
495 | return nsm; | 498 | return nsm; |
496 | } | 499 | } |
497 | 500 | ||
498 | struct nsm_handle * | 501 | static struct nsm_handle * |
499 | nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) | 502 | nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) |
500 | { | 503 | { |
501 | return __nsm_find(sin, hostname, hostname_len, 1); | 504 | return __nsm_find(sin, hostname, hostname_len, 1); |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 0ce5c81ff507..f67146a8199a 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -234,7 +234,7 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
234 | */ | 234 | */ |
235 | static void nlm4svc_callback_exit(struct rpc_task *task, void *data) | 235 | static void nlm4svc_callback_exit(struct rpc_task *task, void *data) |
236 | { | 236 | { |
237 | dprintk("lockd: %4d callback returned %d\n", task->tk_pid, | 237 | dprintk("lockd: %5u callback returned %d\n", task->tk_pid, |
238 | -task->tk_status); | 238 | -task->tk_status); |
239 | } | 239 | } |
240 | 240 | ||
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 7e219b938552..c7db0a5bccdc 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -343,8 +343,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
343 | __be32 ret; | 343 | __be32 ret; |
344 | 344 | ||
345 | dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n", | 345 | dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n", |
346 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 346 | file->f_file->f_path.dentry->d_inode->i_sb->s_id, |
347 | file->f_file->f_dentry->d_inode->i_ino, | 347 | file->f_file->f_path.dentry->d_inode->i_ino, |
348 | lock->fl.fl_type, lock->fl.fl_pid, | 348 | lock->fl.fl_type, lock->fl.fl_pid, |
349 | (long long)lock->fl.fl_start, | 349 | (long long)lock->fl.fl_start, |
350 | (long long)lock->fl.fl_end, | 350 | (long long)lock->fl.fl_end, |
@@ -420,8 +420,8 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock, | |||
420 | struct nlm_lock *conflock) | 420 | struct nlm_lock *conflock) |
421 | { | 421 | { |
422 | dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", | 422 | dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", |
423 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 423 | file->f_file->f_path.dentry->d_inode->i_sb->s_id, |
424 | file->f_file->f_dentry->d_inode->i_ino, | 424 | file->f_file->f_path.dentry->d_inode->i_ino, |
425 | lock->fl.fl_type, | 425 | lock->fl.fl_type, |
426 | (long long)lock->fl.fl_start, | 426 | (long long)lock->fl.fl_start, |
427 | (long long)lock->fl.fl_end); | 427 | (long long)lock->fl.fl_end); |
@@ -454,8 +454,8 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) | |||
454 | int error; | 454 | int error; |
455 | 455 | ||
456 | dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n", | 456 | dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n", |
457 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 457 | file->f_file->f_path.dentry->d_inode->i_sb->s_id, |
458 | file->f_file->f_dentry->d_inode->i_ino, | 458 | file->f_file->f_path.dentry->d_inode->i_ino, |
459 | lock->fl.fl_pid, | 459 | lock->fl.fl_pid, |
460 | (long long)lock->fl.fl_start, | 460 | (long long)lock->fl.fl_start, |
461 | (long long)lock->fl.fl_end); | 461 | (long long)lock->fl.fl_end); |
@@ -483,8 +483,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | |||
483 | int status = 0; | 483 | int status = 0; |
484 | 484 | ||
485 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", | 485 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", |
486 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 486 | file->f_file->f_path.dentry->d_inode->i_sb->s_id, |
487 | file->f_file->f_dentry->d_inode->i_ino, | 487 | file->f_file->f_path.dentry->d_inode->i_ino, |
488 | lock->fl.fl_pid, | 488 | lock->fl.fl_pid, |
489 | (long long)lock->fl.fl_start, | 489 | (long long)lock->fl.fl_start, |
490 | (long long)lock->fl.fl_end); | 490 | (long long)lock->fl.fl_end); |
@@ -645,7 +645,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops = { | |||
645 | * block. | 645 | * block. |
646 | */ | 646 | */ |
647 | void | 647 | void |
648 | nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) | 648 | nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status) |
649 | { | 649 | { |
650 | struct nlm_block *block; | 650 | struct nlm_block *block; |
651 | 651 | ||
@@ -655,7 +655,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status) | |||
655 | return; | 655 | return; |
656 | 656 | ||
657 | if (block) { | 657 | if (block) { |
658 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { | 658 | if (status == nlm_lck_denied_grace_period) { |
659 | /* Try again in a couple of seconds */ | 659 | /* Try again in a couple of seconds */ |
660 | nlmsvc_insert_block(block, 10 * HZ); | 660 | nlmsvc_insert_block(block, 10 * HZ); |
661 | } else { | 661 | } else { |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 32e99a6e8dca..3707c3a23e93 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -263,7 +263,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
263 | */ | 263 | */ |
264 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) | 264 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) |
265 | { | 265 | { |
266 | dprintk("lockd: %4d callback returned %d\n", task->tk_pid, | 266 | dprintk("lockd: %5u callback returned %d\n", task->tk_pid, |
267 | -task->tk_status); | 267 | -task->tk_status); |
268 | } | 268 | } |
269 | 269 | ||
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c index 6220dc2a3f2c..068886de4dda 100644 --- a/fs/lockd/svcshare.c +++ b/fs/lockd/svcshare.c | |||
@@ -39,7 +39,7 @@ nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file, | |||
39 | return nlm_lck_denied; | 39 | return nlm_lck_denied; |
40 | } | 40 | } |
41 | 41 | ||
42 | share = (struct nlm_share *) kmalloc(sizeof(*share) + oh->len, | 42 | share = kmalloc(sizeof(*share) + oh->len, |
43 | GFP_KERNEL); | 43 | GFP_KERNEL); |
44 | if (share == NULL) | 44 | if (share == NULL) |
45 | return nlm_lck_denied_nolocks; | 45 | return nlm_lck_denied_nolocks; |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index e83024e16042..c0df00c74ce3 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -43,7 +43,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f) | |||
43 | 43 | ||
44 | static inline void nlm_debug_print_file(char *msg, struct nlm_file *file) | 44 | static inline void nlm_debug_print_file(char *msg, struct nlm_file *file) |
45 | { | 45 | { |
46 | struct inode *inode = file->f_file->f_dentry->d_inode; | 46 | struct inode *inode = file->f_file->f_path.dentry->d_inode; |
47 | 47 | ||
48 | dprintk("lockd: %s %s/%ld\n", | 48 | dprintk("lockd: %s %s/%ld\n", |
49 | msg, inode->i_sb->s_id, inode->i_ino); | 49 | msg, inode->i_sb->s_id, inode->i_ino); |
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index b7c949256e5a..34dae5d70738 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c | |||
@@ -361,7 +361,7 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) | |||
361 | { | 361 | { |
362 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | 362 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) |
363 | return 0; | 363 | return 0; |
364 | resp->status = ntohl(*p++); | 364 | resp->status = *p++; |
365 | return xdr_argsize_check(rqstp, p); | 365 | return xdr_argsize_check(rqstp, p); |
366 | } | 366 | } |
367 | 367 | ||
@@ -407,8 +407,8 @@ nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
407 | { | 407 | { |
408 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | 408 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) |
409 | return -EIO; | 409 | return -EIO; |
410 | resp->status = ntohl(*p++); | 410 | resp->status = *p++; |
411 | if (resp->status == NLM_LCK_DENIED) { | 411 | if (resp->status == nlm_lck_denied) { |
412 | struct file_lock *fl = &resp->lock.fl; | 412 | struct file_lock *fl = &resp->lock.fl; |
413 | u32 excl; | 413 | u32 excl; |
414 | s32 start, len, end; | 414 | s32 start, len, end; |
@@ -506,7 +506,7 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
506 | { | 506 | { |
507 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | 507 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) |
508 | return -EIO; | 508 | return -EIO; |
509 | resp->status = ntohl(*p++); | 509 | resp->status = *p++; |
510 | return 0; | 510 | return 0; |
511 | } | 511 | } |
512 | 512 | ||
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index f4c0b2b9f75a..a78240551219 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
@@ -367,7 +367,7 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) | |||
367 | { | 367 | { |
368 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) | 368 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) |
369 | return 0; | 369 | return 0; |
370 | resp->status = ntohl(*p++); | 370 | resp->status = *p++; |
371 | return xdr_argsize_check(rqstp, p); | 371 | return xdr_argsize_check(rqstp, p); |
372 | } | 372 | } |
373 | 373 | ||
@@ -413,8 +413,8 @@ nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
413 | { | 413 | { |
414 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) | 414 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) |
415 | return -EIO; | 415 | return -EIO; |
416 | resp->status = ntohl(*p++); | 416 | resp->status = *p++; |
417 | if (resp->status == NLM_LCK_DENIED) { | 417 | if (resp->status == nlm_lck_denied) { |
418 | struct file_lock *fl = &resp->lock.fl; | 418 | struct file_lock *fl = &resp->lock.fl; |
419 | u32 excl; | 419 | u32 excl; |
420 | s64 start, end, len; | 420 | s64 start, end, len; |
@@ -512,7 +512,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
512 | { | 512 | { |
513 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) | 513 | if (!(p = nlm4_decode_cookie(p, &resp->cookie))) |
514 | return -EIO; | 514 | return -EIO; |
515 | resp->status = ntohl(*p++); | 515 | resp->status = *p++; |
516 | return 0; | 516 | return 0; |
517 | } | 517 | } |
518 | 518 | ||
diff --git a/fs/locks.c b/fs/locks.c index e0b6a80649a0..52a81005dab4 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -142,12 +142,12 @@ int lease_break_time = 45; | |||
142 | static LIST_HEAD(file_lock_list); | 142 | static LIST_HEAD(file_lock_list); |
143 | static LIST_HEAD(blocked_list); | 143 | static LIST_HEAD(blocked_list); |
144 | 144 | ||
145 | static kmem_cache_t *filelock_cache __read_mostly; | 145 | static struct kmem_cache *filelock_cache __read_mostly; |
146 | 146 | ||
147 | /* Allocate an empty lock structure. */ | 147 | /* Allocate an empty lock structure. */ |
148 | static struct file_lock *locks_alloc_lock(void) | 148 | static struct file_lock *locks_alloc_lock(void) |
149 | { | 149 | { |
150 | return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); | 150 | return kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void locks_release_private(struct file_lock *fl) | 153 | static void locks_release_private(struct file_lock *fl) |
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock); | |||
199 | * Initialises the fields of the file lock which are invariant for | 199 | * Initialises the fields of the file lock which are invariant for |
200 | * free file_locks. | 200 | * free file_locks. |
201 | */ | 201 | */ |
202 | static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) | 202 | static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) |
203 | { | 203 | { |
204 | struct file_lock *lock = (struct file_lock *) foo; | 204 | struct file_lock *lock = (struct file_lock *) foo; |
205 | 205 | ||
@@ -321,7 +321,7 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
321 | start = filp->f_pos; | 321 | start = filp->f_pos; |
322 | break; | 322 | break; |
323 | case SEEK_END: | 323 | case SEEK_END: |
324 | start = i_size_read(filp->f_dentry->d_inode); | 324 | start = i_size_read(filp->f_path.dentry->d_inode); |
325 | break; | 325 | break; |
326 | default: | 326 | default: |
327 | return -EINVAL; | 327 | return -EINVAL; |
@@ -371,7 +371,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
371 | start = filp->f_pos; | 371 | start = filp->f_pos; |
372 | break; | 372 | break; |
373 | case SEEK_END: | 373 | case SEEK_END: |
374 | start = i_size_read(filp->f_dentry->d_inode); | 374 | start = i_size_read(filp->f_path.dentry->d_inode); |
375 | break; | 375 | break; |
376 | default: | 376 | default: |
377 | return -EINVAL; | 377 | return -EINVAL; |
@@ -672,7 +672,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl, | |||
672 | struct file_lock *cfl; | 672 | struct file_lock *cfl; |
673 | 673 | ||
674 | lock_kernel(); | 674 | lock_kernel(); |
675 | for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { | 675 | for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { |
676 | if (!IS_POSIX(cfl)) | 676 | if (!IS_POSIX(cfl)) |
677 | continue; | 677 | continue; |
678 | if (posix_locks_conflict(cfl, fl)) | 678 | if (posix_locks_conflict(cfl, fl)) |
@@ -734,7 +734,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) | |||
734 | { | 734 | { |
735 | struct file_lock *new_fl = NULL; | 735 | struct file_lock *new_fl = NULL; |
736 | struct file_lock **before; | 736 | struct file_lock **before; |
737 | struct inode * inode = filp->f_dentry->d_inode; | 737 | struct inode * inode = filp->f_path.dentry->d_inode; |
738 | int error = 0; | 738 | int error = 0; |
739 | int found = 0; | 739 | int found = 0; |
740 | 740 | ||
@@ -1018,7 +1018,7 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request | |||
1018 | */ | 1018 | */ |
1019 | int posix_lock_file(struct file *filp, struct file_lock *fl) | 1019 | int posix_lock_file(struct file *filp, struct file_lock *fl) |
1020 | { | 1020 | { |
1021 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL); | 1021 | return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, NULL); |
1022 | } | 1022 | } |
1023 | EXPORT_SYMBOL(posix_lock_file); | 1023 | EXPORT_SYMBOL(posix_lock_file); |
1024 | 1024 | ||
@@ -1033,7 +1033,7 @@ EXPORT_SYMBOL(posix_lock_file); | |||
1033 | int posix_lock_file_conf(struct file *filp, struct file_lock *fl, | 1033 | int posix_lock_file_conf(struct file *filp, struct file_lock *fl, |
1034 | struct file_lock *conflock) | 1034 | struct file_lock *conflock) |
1035 | { | 1035 | { |
1036 | return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock); | 1036 | return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, conflock); |
1037 | } | 1037 | } |
1038 | EXPORT_SYMBOL(posix_lock_file_conf); | 1038 | EXPORT_SYMBOL(posix_lock_file_conf); |
1039 | 1039 | ||
@@ -1333,8 +1333,8 @@ int fcntl_getlease(struct file *filp) | |||
1333 | int type = F_UNLCK; | 1333 | int type = F_UNLCK; |
1334 | 1334 | ||
1335 | lock_kernel(); | 1335 | lock_kernel(); |
1336 | time_out_leases(filp->f_dentry->d_inode); | 1336 | time_out_leases(filp->f_path.dentry->d_inode); |
1337 | for (fl = filp->f_dentry->d_inode->i_flock; fl && IS_LEASE(fl); | 1337 | for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl); |
1338 | fl = fl->fl_next) { | 1338 | fl = fl->fl_next) { |
1339 | if (fl->fl_file == filp) { | 1339 | if (fl->fl_file == filp) { |
1340 | type = fl->fl_type & ~F_INPROGRESS; | 1340 | type = fl->fl_type & ~F_INPROGRESS; |
@@ -1359,7 +1359,7 @@ int fcntl_getlease(struct file *filp) | |||
1359 | static int __setlease(struct file *filp, long arg, struct file_lock **flp) | 1359 | static int __setlease(struct file *filp, long arg, struct file_lock **flp) |
1360 | { | 1360 | { |
1361 | struct file_lock *fl, **before, **my_before = NULL, *lease; | 1361 | struct file_lock *fl, **before, **my_before = NULL, *lease; |
1362 | struct dentry *dentry = filp->f_dentry; | 1362 | struct dentry *dentry = filp->f_path.dentry; |
1363 | struct inode *inode = dentry->d_inode; | 1363 | struct inode *inode = dentry->d_inode; |
1364 | int error, rdlease_count = 0, wrlease_count = 0; | 1364 | int error, rdlease_count = 0, wrlease_count = 0; |
1365 | 1365 | ||
@@ -1448,7 +1448,7 @@ out: | |||
1448 | 1448 | ||
1449 | int setlease(struct file *filp, long arg, struct file_lock **lease) | 1449 | int setlease(struct file *filp, long arg, struct file_lock **lease) |
1450 | { | 1450 | { |
1451 | struct dentry *dentry = filp->f_dentry; | 1451 | struct dentry *dentry = filp->f_path.dentry; |
1452 | struct inode *inode = dentry->d_inode; | 1452 | struct inode *inode = dentry->d_inode; |
1453 | int error; | 1453 | int error; |
1454 | 1454 | ||
@@ -1482,7 +1482,7 @@ EXPORT_SYMBOL(setlease); | |||
1482 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) | 1482 | int fcntl_setlease(unsigned int fd, struct file *filp, long arg) |
1483 | { | 1483 | { |
1484 | struct file_lock fl, *flp = &fl; | 1484 | struct file_lock fl, *flp = &fl; |
1485 | struct dentry *dentry = filp->f_dentry; | 1485 | struct dentry *dentry = filp->f_path.dentry; |
1486 | struct inode *inode = dentry->d_inode; | 1486 | struct inode *inode = dentry->d_inode; |
1487 | int error; | 1487 | int error; |
1488 | 1488 | ||
@@ -1692,7 +1692,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, | |||
1692 | if (copy_from_user(&flock, l, sizeof(flock))) | 1692 | if (copy_from_user(&flock, l, sizeof(flock))) |
1693 | goto out; | 1693 | goto out; |
1694 | 1694 | ||
1695 | inode = filp->f_dentry->d_inode; | 1695 | inode = filp->f_path.dentry->d_inode; |
1696 | 1696 | ||
1697 | /* Don't allow mandatory locks on files that may be memory mapped | 1697 | /* Don't allow mandatory locks on files that may be memory mapped |
1698 | * and shared. | 1698 | * and shared. |
@@ -1835,7 +1835,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, | |||
1835 | if (copy_from_user(&flock, l, sizeof(flock))) | 1835 | if (copy_from_user(&flock, l, sizeof(flock))) |
1836 | goto out; | 1836 | goto out; |
1837 | 1837 | ||
1838 | inode = filp->f_dentry->d_inode; | 1838 | inode = filp->f_path.dentry->d_inode; |
1839 | 1839 | ||
1840 | /* Don't allow mandatory locks on files that may be memory mapped | 1840 | /* Don't allow mandatory locks on files that may be memory mapped |
1841 | * and shared. | 1841 | * and shared. |
@@ -1922,7 +1922,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) | |||
1922 | * posix_lock_file(). Another process could be setting a lock on this | 1922 | * posix_lock_file(). Another process could be setting a lock on this |
1923 | * file at the same time, but we wouldn't remove that lock anyway. | 1923 | * file at the same time, but we wouldn't remove that lock anyway. |
1924 | */ | 1924 | */ |
1925 | if (!filp->f_dentry->d_inode->i_flock) | 1925 | if (!filp->f_path.dentry->d_inode->i_flock) |
1926 | return; | 1926 | return; |
1927 | 1927 | ||
1928 | lock.fl_type = F_UNLCK; | 1928 | lock.fl_type = F_UNLCK; |
@@ -1951,7 +1951,7 @@ EXPORT_SYMBOL(locks_remove_posix); | |||
1951 | */ | 1951 | */ |
1952 | void locks_remove_flock(struct file *filp) | 1952 | void locks_remove_flock(struct file *filp) |
1953 | { | 1953 | { |
1954 | struct inode * inode = filp->f_dentry->d_inode; | 1954 | struct inode * inode = filp->f_path.dentry->d_inode; |
1955 | struct file_lock *fl; | 1955 | struct file_lock *fl; |
1956 | struct file_lock **before; | 1956 | struct file_lock **before; |
1957 | 1957 | ||
@@ -2020,7 +2020,7 @@ static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx) | |||
2020 | struct inode *inode = NULL; | 2020 | struct inode *inode = NULL; |
2021 | 2021 | ||
2022 | if (fl->fl_file != NULL) | 2022 | if (fl->fl_file != NULL) |
2023 | inode = fl->fl_file->f_dentry->d_inode; | 2023 | inode = fl->fl_file->f_path.dentry->d_inode; |
2024 | 2024 | ||
2025 | out += sprintf(out, "%d:%s ", id, pfx); | 2025 | out += sprintf(out, "%d:%s ", id, pfx); |
2026 | if (IS_POSIX(fl)) { | 2026 | if (IS_POSIX(fl)) { |
diff --git a/fs/mbcache.c b/fs/mbcache.c index 0ff71256e65b..deeb9dc062d9 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -85,7 +85,7 @@ struct mb_cache { | |||
85 | #ifndef MB_CACHE_INDEXES_COUNT | 85 | #ifndef MB_CACHE_INDEXES_COUNT |
86 | int c_indexes_count; | 86 | int c_indexes_count; |
87 | #endif | 87 | #endif |
88 | kmem_cache_t *c_entry_cache; | 88 | struct kmem_cache *c_entry_cache; |
89 | struct list_head *c_block_hash; | 89 | struct list_head *c_block_hash; |
90 | struct list_head *c_indexes_hash[0]; | 90 | struct list_head *c_indexes_hash[0]; |
91 | }; | 91 | }; |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 2b0a389d1987..ab782c4086f5 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -82,7 +82,7 @@ static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi) | |||
82 | static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) | 82 | static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) |
83 | { | 83 | { |
84 | unsigned long pos = filp->f_pos; | 84 | unsigned long pos = filp->f_pos; |
85 | struct inode *inode = filp->f_dentry->d_inode; | 85 | struct inode *inode = filp->f_path.dentry->d_inode; |
86 | struct super_block *sb = inode->i_sb; | 86 | struct super_block *sb = inode->i_sb; |
87 | unsigned offset = pos & ~PAGE_CACHE_MASK; | 87 | unsigned offset = pos & ~PAGE_CACHE_MASK; |
88 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 88 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1e36bae4d0eb..629e09b38c5c 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -51,12 +51,12 @@ static void minix_put_super(struct super_block *sb) | |||
51 | return; | 51 | return; |
52 | } | 52 | } |
53 | 53 | ||
54 | static kmem_cache_t * minix_inode_cachep; | 54 | static struct kmem_cache * minix_inode_cachep; |
55 | 55 | ||
56 | static struct inode *minix_alloc_inode(struct super_block *sb) | 56 | static struct inode *minix_alloc_inode(struct super_block *sb) |
57 | { | 57 | { |
58 | struct minix_inode_info *ei; | 58 | struct minix_inode_info *ei; |
59 | ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, SLAB_KERNEL); | 59 | ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); |
60 | if (!ei) | 60 | if (!ei) |
61 | return NULL; | 61 | return NULL; |
62 | return &ei->vfs_inode; | 62 | return &ei->vfs_inode; |
@@ -67,7 +67,7 @@ static void minix_destroy_inode(struct inode *inode) | |||
67 | kmem_cache_free(minix_inode_cachep, minix_i(inode)); | 67 | kmem_cache_free(minix_inode_cachep, minix_i(inode)); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 70 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
71 | { | 71 | { |
72 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; | 72 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; |
73 | 73 | ||
diff --git a/fs/namei.c b/fs/namei.c index 28d49b301d55..e4f108f08230 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -249,9 +249,11 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
249 | 249 | ||
250 | /* | 250 | /* |
251 | * MAY_EXEC on regular files requires special handling: We override | 251 | * MAY_EXEC on regular files requires special handling: We override |
252 | * filesystem execute permissions if the mode bits aren't set. | 252 | * filesystem execute permissions if the mode bits aren't set or |
253 | * the fs is mounted with the "noexec" flag. | ||
253 | */ | 254 | */ |
254 | if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) | 255 | if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) || |
256 | (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC)))) | ||
255 | return -EACCES; | 257 | return -EACCES; |
256 | 258 | ||
257 | /* Ordinary permission routines do not understand MAY_APPEND. */ | 259 | /* Ordinary permission routines do not understand MAY_APPEND. */ |
@@ -295,7 +297,7 @@ int vfs_permission(struct nameidata *nd, int mask) | |||
295 | */ | 297 | */ |
296 | int file_permission(struct file *file, int mask) | 298 | int file_permission(struct file *file, int mask) |
297 | { | 299 | { |
298 | return permission(file->f_dentry->d_inode, mask, NULL); | 300 | return permission(file->f_path.dentry->d_inode, mask, NULL); |
299 | } | 301 | } |
300 | 302 | ||
301 | /* | 303 | /* |
@@ -331,7 +333,7 @@ int get_write_access(struct inode * inode) | |||
331 | 333 | ||
332 | int deny_write_access(struct file * file) | 334 | int deny_write_access(struct file * file) |
333 | { | 335 | { |
334 | struct inode *inode = file->f_dentry->d_inode; | 336 | struct inode *inode = file->f_path.dentry->d_inode; |
335 | 337 | ||
336 | spin_lock(&inode->i_lock); | 338 | spin_lock(&inode->i_lock); |
337 | if (atomic_read(&inode->i_writecount) > 0) { | 339 | if (atomic_read(&inode->i_writecount) > 0) { |
@@ -366,7 +368,7 @@ void path_release_on_umount(struct nameidata *nd) | |||
366 | */ | 368 | */ |
367 | void release_open_intent(struct nameidata *nd) | 369 | void release_open_intent(struct nameidata *nd) |
368 | { | 370 | { |
369 | if (nd->intent.open.file->f_dentry == NULL) | 371 | if (nd->intent.open.file->f_path.dentry == NULL) |
370 | put_filp(nd->intent.open.file); | 372 | put_filp(nd->intent.open.file); |
371 | else | 373 | else |
372 | fput(nd->intent.open.file); | 374 | fput(nd->intent.open.file); |
@@ -570,11 +572,6 @@ fail: | |||
570 | return PTR_ERR(link); | 572 | return PTR_ERR(link); |
571 | } | 573 | } |
572 | 574 | ||
573 | struct path { | ||
574 | struct vfsmount *mnt; | ||
575 | struct dentry *dentry; | ||
576 | }; | ||
577 | |||
578 | static inline void dput_path(struct path *path, struct nameidata *nd) | 575 | static inline void dput_path(struct path *path, struct nameidata *nd) |
579 | { | 576 | { |
580 | dput(path->dentry); | 577 | dput(path->dentry); |
@@ -1141,7 +1138,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1141 | if (!file) | 1138 | if (!file) |
1142 | goto out_fail; | 1139 | goto out_fail; |
1143 | 1140 | ||
1144 | dentry = file->f_dentry; | 1141 | dentry = file->f_path.dentry; |
1145 | 1142 | ||
1146 | retval = -ENOTDIR; | 1143 | retval = -ENOTDIR; |
1147 | if (!S_ISDIR(dentry->d_inode->i_mode)) | 1144 | if (!S_ISDIR(dentry->d_inode->i_mode)) |
@@ -1151,7 +1148,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1151 | if (retval) | 1148 | if (retval) |
1152 | goto fput_fail; | 1149 | goto fput_fail; |
1153 | 1150 | ||
1154 | nd->mnt = mntget(file->f_vfsmnt); | 1151 | nd->mnt = mntget(file->f_path.mnt); |
1155 | nd->dentry = dget(dentry); | 1152 | nd->dentry = dget(dentry); |
1156 | 1153 | ||
1157 | fput_light(file, fput_needed); | 1154 | fput_light(file, fput_needed); |
@@ -1996,8 +1993,7 @@ asmlinkage long sys_mkdir(const char __user *pathname, int mode) | |||
1996 | void dentry_unhash(struct dentry *dentry) | 1993 | void dentry_unhash(struct dentry *dentry) |
1997 | { | 1994 | { |
1998 | dget(dentry); | 1995 | dget(dentry); |
1999 | if (atomic_read(&dentry->d_count)) | 1996 | shrink_dcache_parent(dentry); |
2000 | shrink_dcache_parent(dentry); | ||
2001 | spin_lock(&dcache_lock); | 1997 | spin_lock(&dcache_lock); |
2002 | spin_lock(&dentry->d_lock); | 1998 | spin_lock(&dentry->d_lock); |
2003 | if (atomic_read(&dentry->d_count) == 2) | 1999 | if (atomic_read(&dentry->d_count) == 2) |
diff --git a/fs/namespace.c b/fs/namespace.c index 55442a6cf221..5ef336c1103c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/sysfs.h> | 21 | #include <linux/sysfs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/namespace.h> | 23 | #include <linux/mnt_namespace.h> |
24 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
25 | #include <linux/security.h> | 25 | #include <linux/security.h> |
26 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
@@ -36,7 +36,7 @@ static int event; | |||
36 | 36 | ||
37 | static struct list_head *mount_hashtable __read_mostly; | 37 | static struct list_head *mount_hashtable __read_mostly; |
38 | static int hash_mask __read_mostly, hash_bits __read_mostly; | 38 | static int hash_mask __read_mostly, hash_bits __read_mostly; |
39 | static kmem_cache_t *mnt_cache __read_mostly; | 39 | static struct kmem_cache *mnt_cache __read_mostly; |
40 | static struct rw_semaphore namespace_sem; | 40 | static struct rw_semaphore namespace_sem; |
41 | 41 | ||
42 | /* /sys/fs */ | 42 | /* /sys/fs */ |
@@ -133,10 +133,10 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry) | |||
133 | 133 | ||
134 | static inline int check_mnt(struct vfsmount *mnt) | 134 | static inline int check_mnt(struct vfsmount *mnt) |
135 | { | 135 | { |
136 | return mnt->mnt_namespace == current->nsproxy->namespace; | 136 | return mnt->mnt_ns == current->nsproxy->mnt_ns; |
137 | } | 137 | } |
138 | 138 | ||
139 | static void touch_namespace(struct namespace *ns) | 139 | static void touch_mnt_namespace(struct mnt_namespace *ns) |
140 | { | 140 | { |
141 | if (ns) { | 141 | if (ns) { |
142 | ns->event = ++event; | 142 | ns->event = ++event; |
@@ -144,7 +144,7 @@ static void touch_namespace(struct namespace *ns) | |||
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | static void __touch_namespace(struct namespace *ns) | 147 | static void __touch_mnt_namespace(struct mnt_namespace *ns) |
148 | { | 148 | { |
149 | if (ns && ns->event != event) { | 149 | if (ns && ns->event != event) { |
150 | ns->event = event; | 150 | ns->event = event; |
@@ -187,19 +187,19 @@ static void commit_tree(struct vfsmount *mnt) | |||
187 | struct vfsmount *parent = mnt->mnt_parent; | 187 | struct vfsmount *parent = mnt->mnt_parent; |
188 | struct vfsmount *m; | 188 | struct vfsmount *m; |
189 | LIST_HEAD(head); | 189 | LIST_HEAD(head); |
190 | struct namespace *n = parent->mnt_namespace; | 190 | struct mnt_namespace *n = parent->mnt_ns; |
191 | 191 | ||
192 | BUG_ON(parent == mnt); | 192 | BUG_ON(parent == mnt); |
193 | 193 | ||
194 | list_add_tail(&head, &mnt->mnt_list); | 194 | list_add_tail(&head, &mnt->mnt_list); |
195 | list_for_each_entry(m, &head, mnt_list) | 195 | list_for_each_entry(m, &head, mnt_list) |
196 | m->mnt_namespace = n; | 196 | m->mnt_ns = n; |
197 | list_splice(&head, n->list.prev); | 197 | list_splice(&head, n->list.prev); |
198 | 198 | ||
199 | list_add_tail(&mnt->mnt_hash, mount_hashtable + | 199 | list_add_tail(&mnt->mnt_hash, mount_hashtable + |
200 | hash(parent, mnt->mnt_mountpoint)); | 200 | hash(parent, mnt->mnt_mountpoint)); |
201 | list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); | 201 | list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); |
202 | touch_namespace(n); | 202 | touch_mnt_namespace(n); |
203 | } | 203 | } |
204 | 204 | ||
205 | static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root) | 205 | static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root) |
@@ -320,7 +320,7 @@ EXPORT_SYMBOL(mnt_unpin); | |||
320 | /* iterator */ | 320 | /* iterator */ |
321 | static void *m_start(struct seq_file *m, loff_t *pos) | 321 | static void *m_start(struct seq_file *m, loff_t *pos) |
322 | { | 322 | { |
323 | struct namespace *n = m->private; | 323 | struct mnt_namespace *n = m->private; |
324 | struct list_head *p; | 324 | struct list_head *p; |
325 | loff_t l = *pos; | 325 | loff_t l = *pos; |
326 | 326 | ||
@@ -333,7 +333,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
333 | 333 | ||
334 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) | 334 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) |
335 | { | 335 | { |
336 | struct namespace *n = m->private; | 336 | struct mnt_namespace *n = m->private; |
337 | struct list_head *p = ((struct vfsmount *)v)->mnt_list.next; | 337 | struct list_head *p = ((struct vfsmount *)v)->mnt_list.next; |
338 | (*pos)++; | 338 | (*pos)++; |
339 | return p == &n->list ? NULL : list_entry(p, struct vfsmount, mnt_list); | 339 | return p == &n->list ? NULL : list_entry(p, struct vfsmount, mnt_list); |
@@ -368,6 +368,7 @@ static int show_vfsmnt(struct seq_file *m, void *v) | |||
368 | { MNT_NOEXEC, ",noexec" }, | 368 | { MNT_NOEXEC, ",noexec" }, |
369 | { MNT_NOATIME, ",noatime" }, | 369 | { MNT_NOATIME, ",noatime" }, |
370 | { MNT_NODIRATIME, ",nodiratime" }, | 370 | { MNT_NODIRATIME, ",nodiratime" }, |
371 | { MNT_RELATIME, ",relatime" }, | ||
371 | { 0, NULL } | 372 | { 0, NULL } |
372 | }; | 373 | }; |
373 | struct proc_fs_info *fs_infop; | 374 | struct proc_fs_info *fs_infop; |
@@ -526,8 +527,8 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | |||
526 | list_for_each_entry(p, kill, mnt_hash) { | 527 | list_for_each_entry(p, kill, mnt_hash) { |
527 | list_del_init(&p->mnt_expire); | 528 | list_del_init(&p->mnt_expire); |
528 | list_del_init(&p->mnt_list); | 529 | list_del_init(&p->mnt_list); |
529 | __touch_namespace(p->mnt_namespace); | 530 | __touch_mnt_namespace(p->mnt_ns); |
530 | p->mnt_namespace = NULL; | 531 | p->mnt_ns = NULL; |
531 | list_del_init(&p->mnt_child); | 532 | list_del_init(&p->mnt_child); |
532 | if (p->mnt_parent != p) | 533 | if (p->mnt_parent != p) |
533 | p->mnt_mountpoint->d_mounted--; | 534 | p->mnt_mountpoint->d_mounted--; |
@@ -830,7 +831,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, | |||
830 | if (parent_nd) { | 831 | if (parent_nd) { |
831 | detach_mnt(source_mnt, parent_nd); | 832 | detach_mnt(source_mnt, parent_nd); |
832 | attach_mnt(source_mnt, nd); | 833 | attach_mnt(source_mnt, nd); |
833 | touch_namespace(current->nsproxy->namespace); | 834 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
834 | } else { | 835 | } else { |
835 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); | 836 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); |
836 | commit_tree(source_mnt); | 837 | commit_tree(source_mnt); |
@@ -1145,9 +1146,9 @@ static void expire_mount(struct vfsmount *mnt, struct list_head *mounts, | |||
1145 | */ | 1146 | */ |
1146 | if (!propagate_mount_busy(mnt, 2)) { | 1147 | if (!propagate_mount_busy(mnt, 2)) { |
1147 | /* delete from the namespace */ | 1148 | /* delete from the namespace */ |
1148 | touch_namespace(mnt->mnt_namespace); | 1149 | touch_mnt_namespace(mnt->mnt_ns); |
1149 | list_del_init(&mnt->mnt_list); | 1150 | list_del_init(&mnt->mnt_list); |
1150 | mnt->mnt_namespace = NULL; | 1151 | mnt->mnt_ns = NULL; |
1151 | umount_tree(mnt, 1, umounts); | 1152 | umount_tree(mnt, 1, umounts); |
1152 | spin_unlock(&vfsmount_lock); | 1153 | spin_unlock(&vfsmount_lock); |
1153 | } else { | 1154 | } else { |
@@ -1168,7 +1169,7 @@ static void expire_mount(struct vfsmount *mnt, struct list_head *mounts, | |||
1168 | */ | 1169 | */ |
1169 | static void expire_mount_list(struct list_head *graveyard, struct list_head *mounts) | 1170 | static void expire_mount_list(struct list_head *graveyard, struct list_head *mounts) |
1170 | { | 1171 | { |
1171 | struct namespace *namespace; | 1172 | struct mnt_namespace *ns; |
1172 | struct vfsmount *mnt; | 1173 | struct vfsmount *mnt; |
1173 | 1174 | ||
1174 | while (!list_empty(graveyard)) { | 1175 | while (!list_empty(graveyard)) { |
@@ -1178,10 +1179,10 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou | |||
1178 | 1179 | ||
1179 | /* don't do anything if the namespace is dead - all the | 1180 | /* don't do anything if the namespace is dead - all the |
1180 | * vfsmounts from it are going away anyway */ | 1181 | * vfsmounts from it are going away anyway */ |
1181 | namespace = mnt->mnt_namespace; | 1182 | ns = mnt->mnt_ns; |
1182 | if (!namespace || !namespace->root) | 1183 | if (!ns || !ns->root) |
1183 | continue; | 1184 | continue; |
1184 | get_namespace(namespace); | 1185 | get_mnt_ns(ns); |
1185 | 1186 | ||
1186 | spin_unlock(&vfsmount_lock); | 1187 | spin_unlock(&vfsmount_lock); |
1187 | down_write(&namespace_sem); | 1188 | down_write(&namespace_sem); |
@@ -1189,7 +1190,7 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou | |||
1189 | up_write(&namespace_sem); | 1190 | up_write(&namespace_sem); |
1190 | release_mounts(&umounts); | 1191 | release_mounts(&umounts); |
1191 | mntput(mnt); | 1192 | mntput(mnt); |
1192 | put_namespace(namespace); | 1193 | put_mnt_ns(ns); |
1193 | spin_lock(&vfsmount_lock); | 1194 | spin_lock(&vfsmount_lock); |
1194 | } | 1195 | } |
1195 | } | 1196 | } |
@@ -1405,9 +1406,11 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1405 | mnt_flags |= MNT_NOATIME; | 1406 | mnt_flags |= MNT_NOATIME; |
1406 | if (flags & MS_NODIRATIME) | 1407 | if (flags & MS_NODIRATIME) |
1407 | mnt_flags |= MNT_NODIRATIME; | 1408 | mnt_flags |= MNT_NODIRATIME; |
1409 | if (flags & MS_RELATIME) | ||
1410 | mnt_flags |= MNT_RELATIME; | ||
1408 | 1411 | ||
1409 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | | 1412 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | |
1410 | MS_NOATIME | MS_NODIRATIME); | 1413 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME); |
1411 | 1414 | ||
1412 | /* ... and get the mountpoint */ | 1415 | /* ... and get the mountpoint */ |
1413 | retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); | 1416 | retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); |
@@ -1439,14 +1442,15 @@ dput_out: | |||
1439 | * Allocate a new namespace structure and populate it with contents | 1442 | * Allocate a new namespace structure and populate it with contents |
1440 | * copied from the namespace of the passed in task structure. | 1443 | * copied from the namespace of the passed in task structure. |
1441 | */ | 1444 | */ |
1442 | struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | 1445 | struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, |
1446 | struct fs_struct *fs) | ||
1443 | { | 1447 | { |
1444 | struct namespace *namespace = tsk->nsproxy->namespace; | 1448 | struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns; |
1445 | struct namespace *new_ns; | 1449 | struct mnt_namespace *new_ns; |
1446 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; | 1450 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; |
1447 | struct vfsmount *p, *q; | 1451 | struct vfsmount *p, *q; |
1448 | 1452 | ||
1449 | new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); | 1453 | new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); |
1450 | if (!new_ns) | 1454 | if (!new_ns) |
1451 | return NULL; | 1455 | return NULL; |
1452 | 1456 | ||
@@ -1457,7 +1461,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | |||
1457 | 1461 | ||
1458 | down_write(&namespace_sem); | 1462 | down_write(&namespace_sem); |
1459 | /* First pass: copy the tree topology */ | 1463 | /* First pass: copy the tree topology */ |
1460 | new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root, | 1464 | new_ns->root = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, |
1461 | CL_COPY_ALL | CL_EXPIRE); | 1465 | CL_COPY_ALL | CL_EXPIRE); |
1462 | if (!new_ns->root) { | 1466 | if (!new_ns->root) { |
1463 | up_write(&namespace_sem); | 1467 | up_write(&namespace_sem); |
@@ -1473,10 +1477,10 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | |||
1473 | * as belonging to new namespace. We have already acquired a private | 1477 | * as belonging to new namespace. We have already acquired a private |
1474 | * fs_struct, so tsk->fs->lock is not needed. | 1478 | * fs_struct, so tsk->fs->lock is not needed. |
1475 | */ | 1479 | */ |
1476 | p = namespace->root; | 1480 | p = mnt_ns->root; |
1477 | q = new_ns->root; | 1481 | q = new_ns->root; |
1478 | while (p) { | 1482 | while (p) { |
1479 | q->mnt_namespace = new_ns; | 1483 | q->mnt_ns = new_ns; |
1480 | if (fs) { | 1484 | if (fs) { |
1481 | if (p == fs->rootmnt) { | 1485 | if (p == fs->rootmnt) { |
1482 | rootmnt = p; | 1486 | rootmnt = p; |
@@ -1491,7 +1495,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | |||
1491 | fs->altrootmnt = mntget(q); | 1495 | fs->altrootmnt = mntget(q); |
1492 | } | 1496 | } |
1493 | } | 1497 | } |
1494 | p = next_mnt(p, namespace->root); | 1498 | p = next_mnt(p, mnt_ns->root); |
1495 | q = next_mnt(q, new_ns->root); | 1499 | q = next_mnt(q, new_ns->root); |
1496 | } | 1500 | } |
1497 | up_write(&namespace_sem); | 1501 | up_write(&namespace_sem); |
@@ -1506,16 +1510,16 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | |||
1506 | return new_ns; | 1510 | return new_ns; |
1507 | } | 1511 | } |
1508 | 1512 | ||
1509 | int copy_namespace(int flags, struct task_struct *tsk) | 1513 | int copy_mnt_ns(int flags, struct task_struct *tsk) |
1510 | { | 1514 | { |
1511 | struct namespace *namespace = tsk->nsproxy->namespace; | 1515 | struct mnt_namespace *ns = tsk->nsproxy->mnt_ns; |
1512 | struct namespace *new_ns; | 1516 | struct mnt_namespace *new_ns; |
1513 | int err = 0; | 1517 | int err = 0; |
1514 | 1518 | ||
1515 | if (!namespace) | 1519 | if (!ns) |
1516 | return 0; | 1520 | return 0; |
1517 | 1521 | ||
1518 | get_namespace(namespace); | 1522 | get_mnt_ns(ns); |
1519 | 1523 | ||
1520 | if (!(flags & CLONE_NEWNS)) | 1524 | if (!(flags & CLONE_NEWNS)) |
1521 | return 0; | 1525 | return 0; |
@@ -1525,16 +1529,16 @@ int copy_namespace(int flags, struct task_struct *tsk) | |||
1525 | goto out; | 1529 | goto out; |
1526 | } | 1530 | } |
1527 | 1531 | ||
1528 | new_ns = dup_namespace(tsk, tsk->fs); | 1532 | new_ns = dup_mnt_ns(tsk, tsk->fs); |
1529 | if (!new_ns) { | 1533 | if (!new_ns) { |
1530 | err = -ENOMEM; | 1534 | err = -ENOMEM; |
1531 | goto out; | 1535 | goto out; |
1532 | } | 1536 | } |
1533 | 1537 | ||
1534 | tsk->nsproxy->namespace = new_ns; | 1538 | tsk->nsproxy->mnt_ns = new_ns; |
1535 | 1539 | ||
1536 | out: | 1540 | out: |
1537 | put_namespace(namespace); | 1541 | put_mnt_ns(ns); |
1538 | return err; | 1542 | return err; |
1539 | } | 1543 | } |
1540 | 1544 | ||
@@ -1754,7 +1758,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
1754 | detach_mnt(user_nd.mnt, &root_parent); | 1758 | detach_mnt(user_nd.mnt, &root_parent); |
1755 | attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ | 1759 | attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ |
1756 | attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ | 1760 | attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ |
1757 | touch_namespace(current->nsproxy->namespace); | 1761 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
1758 | spin_unlock(&vfsmount_lock); | 1762 | spin_unlock(&vfsmount_lock); |
1759 | chroot_fs_refs(&user_nd, &new_nd); | 1763 | chroot_fs_refs(&user_nd, &new_nd); |
1760 | security_sb_post_pivotroot(&user_nd, &new_nd); | 1764 | security_sb_post_pivotroot(&user_nd, &new_nd); |
@@ -1779,27 +1783,27 @@ out3: | |||
1779 | static void __init init_mount_tree(void) | 1783 | static void __init init_mount_tree(void) |
1780 | { | 1784 | { |
1781 | struct vfsmount *mnt; | 1785 | struct vfsmount *mnt; |
1782 | struct namespace *namespace; | 1786 | struct mnt_namespace *ns; |
1783 | 1787 | ||
1784 | mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); | 1788 | mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); |
1785 | if (IS_ERR(mnt)) | 1789 | if (IS_ERR(mnt)) |
1786 | panic("Can't create rootfs"); | 1790 | panic("Can't create rootfs"); |
1787 | namespace = kmalloc(sizeof(*namespace), GFP_KERNEL); | 1791 | ns = kmalloc(sizeof(*ns), GFP_KERNEL); |
1788 | if (!namespace) | 1792 | if (!ns) |
1789 | panic("Can't allocate initial namespace"); | 1793 | panic("Can't allocate initial namespace"); |
1790 | atomic_set(&namespace->count, 1); | 1794 | atomic_set(&ns->count, 1); |
1791 | INIT_LIST_HEAD(&namespace->list); | 1795 | INIT_LIST_HEAD(&ns->list); |
1792 | init_waitqueue_head(&namespace->poll); | 1796 | init_waitqueue_head(&ns->poll); |
1793 | namespace->event = 0; | 1797 | ns->event = 0; |
1794 | list_add(&mnt->mnt_list, &namespace->list); | 1798 | list_add(&mnt->mnt_list, &ns->list); |
1795 | namespace->root = mnt; | 1799 | ns->root = mnt; |
1796 | mnt->mnt_namespace = namespace; | 1800 | mnt->mnt_ns = ns; |
1797 | 1801 | ||
1798 | init_task.nsproxy->namespace = namespace; | 1802 | init_task.nsproxy->mnt_ns = ns; |
1799 | get_namespace(namespace); | 1803 | get_mnt_ns(ns); |
1800 | 1804 | ||
1801 | set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root); | 1805 | set_fs_pwd(current->fs, ns->root, ns->root->mnt_root); |
1802 | set_fs_root(current->fs, namespace->root, namespace->root->mnt_root); | 1806 | set_fs_root(current->fs, ns->root, ns->root->mnt_root); |
1803 | } | 1807 | } |
1804 | 1808 | ||
1805 | void __init mnt_init(unsigned long mempages) | 1809 | void __init mnt_init(unsigned long mempages) |
@@ -1860,11 +1864,11 @@ void __init mnt_init(unsigned long mempages) | |||
1860 | init_mount_tree(); | 1864 | init_mount_tree(); |
1861 | } | 1865 | } |
1862 | 1866 | ||
1863 | void __put_namespace(struct namespace *namespace) | 1867 | void __put_mnt_ns(struct mnt_namespace *ns) |
1864 | { | 1868 | { |
1865 | struct vfsmount *root = namespace->root; | 1869 | struct vfsmount *root = ns->root; |
1866 | LIST_HEAD(umount_list); | 1870 | LIST_HEAD(umount_list); |
1867 | namespace->root = NULL; | 1871 | ns->root = NULL; |
1868 | spin_unlock(&vfsmount_lock); | 1872 | spin_unlock(&vfsmount_lock); |
1869 | down_write(&namespace_sem); | 1873 | down_write(&namespace_sem); |
1870 | spin_lock(&vfsmount_lock); | 1874 | spin_lock(&vfsmount_lock); |
@@ -1872,5 +1876,5 @@ void __put_namespace(struct namespace *namespace) | |||
1872 | spin_unlock(&vfsmount_lock); | 1876 | spin_unlock(&vfsmount_lock); |
1873 | up_write(&namespace_sem); | 1877 | up_write(&namespace_sem); |
1874 | release_mounts(&umount_list); | 1878 | release_mounts(&umount_list); |
1875 | kfree(namespace); | 1879 | kfree(ns); |
1876 | } | 1880 | } |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 458b3b785194..73747772c3bb 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -402,7 +402,7 @@ static time_t ncp_obtain_mtime(struct dentry *dentry) | |||
402 | 402 | ||
403 | static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir) | 403 | static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir) |
404 | { | 404 | { |
405 | struct dentry *dentry = filp->f_dentry; | 405 | struct dentry *dentry = filp->f_path.dentry; |
406 | struct inode *inode = dentry->d_inode; | 406 | struct inode *inode = dentry->d_inode; |
407 | struct page *page = NULL; | 407 | struct page *page = NULL; |
408 | struct ncp_server *server = NCP_SERVER(inode); | 408 | struct ncp_server *server = NCP_SERVER(inode); |
@@ -554,7 +554,7 @@ static int | |||
554 | ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 554 | ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
555 | struct ncp_cache_control *ctrl, struct ncp_entry_info *entry) | 555 | struct ncp_cache_control *ctrl, struct ncp_entry_info *entry) |
556 | { | 556 | { |
557 | struct dentry *newdent, *dentry = filp->f_dentry; | 557 | struct dentry *newdent, *dentry = filp->f_path.dentry; |
558 | struct inode *newino, *inode = dentry->d_inode; | 558 | struct inode *newino, *inode = dentry->d_inode; |
559 | struct ncp_cache_control ctl = *ctrl; | 559 | struct ncp_cache_control ctl = *ctrl; |
560 | struct qstr qname; | 560 | struct qstr qname; |
@@ -649,7 +649,7 @@ static void | |||
649 | ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir, | 649 | ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir, |
650 | struct ncp_cache_control *ctl) | 650 | struct ncp_cache_control *ctl) |
651 | { | 651 | { |
652 | struct dentry *dentry = filp->f_dentry; | 652 | struct dentry *dentry = filp->f_path.dentry; |
653 | struct inode *inode = dentry->d_inode; | 653 | struct inode *inode = dentry->d_inode; |
654 | struct ncp_server *server = NCP_SERVER(inode); | 654 | struct ncp_server *server = NCP_SERVER(inode); |
655 | struct ncp_volume_info info; | 655 | struct ncp_volume_info info; |
@@ -685,7 +685,7 @@ static void | |||
685 | ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, | 685 | ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir, |
686 | struct ncp_cache_control *ctl) | 686 | struct ncp_cache_control *ctl) |
687 | { | 687 | { |
688 | struct dentry *dentry = filp->f_dentry; | 688 | struct dentry *dentry = filp->f_path.dentry; |
689 | struct inode *dir = dentry->d_inode; | 689 | struct inode *dir = dentry->d_inode; |
690 | struct ncp_server *server = NCP_SERVER(dir); | 690 | struct ncp_server *server = NCP_SERVER(dir); |
691 | struct nw_search_sequence seq; | 691 | struct nw_search_sequence seq; |
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index df37524b85db..b91fea03b1c3 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -101,7 +101,7 @@ out: | |||
101 | static ssize_t | 101 | static ssize_t |
102 | ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 102 | ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
103 | { | 103 | { |
104 | struct dentry *dentry = file->f_dentry; | 104 | struct dentry *dentry = file->f_path.dentry; |
105 | struct inode *inode = dentry->d_inode; | 105 | struct inode *inode = dentry->d_inode; |
106 | size_t already_read = 0; | 106 | size_t already_read = 0; |
107 | off_t pos; | 107 | off_t pos; |
@@ -182,7 +182,7 @@ outrel: | |||
182 | static ssize_t | 182 | static ssize_t |
183 | ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 183 | ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
184 | { | 184 | { |
185 | struct dentry *dentry = file->f_dentry; | 185 | struct dentry *dentry = file->f_path.dentry; |
186 | struct inode *inode = dentry->d_inode; | 186 | struct inode *inode = dentry->d_inode; |
187 | size_t already_written = 0; | 187 | size_t already_written = 0; |
188 | off_t pos; | 188 | off_t pos; |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 42e3bef270c9..67a90bf795d5 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -40,12 +40,12 @@ static void ncp_delete_inode(struct inode *); | |||
40 | static void ncp_put_super(struct super_block *); | 40 | static void ncp_put_super(struct super_block *); |
41 | static int ncp_statfs(struct dentry *, struct kstatfs *); | 41 | static int ncp_statfs(struct dentry *, struct kstatfs *); |
42 | 42 | ||
43 | static kmem_cache_t * ncp_inode_cachep; | 43 | static struct kmem_cache * ncp_inode_cachep; |
44 | 44 | ||
45 | static struct inode *ncp_alloc_inode(struct super_block *sb) | 45 | static struct inode *ncp_alloc_inode(struct super_block *sb) |
46 | { | 46 | { |
47 | struct ncp_inode_info *ei; | 47 | struct ncp_inode_info *ei; |
48 | ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, SLAB_KERNEL); | 48 | ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL); |
49 | if (!ei) | 49 | if (!ei) |
50 | return NULL; | 50 | return NULL; |
51 | return &ei->vfs_inode; | 51 | return &ei->vfs_inode; |
@@ -56,7 +56,7 @@ static void ncp_destroy_inode(struct inode *inode) | |||
56 | kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); | 56 | kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 59 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
60 | { | 60 | { |
61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; | 61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; |
62 | 62 | ||
@@ -327,11 +327,12 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
327 | char *optarg; | 327 | char *optarg; |
328 | unsigned long optint; | 328 | unsigned long optint; |
329 | int version = 0; | 329 | int version = 0; |
330 | int ret; | ||
330 | 331 | ||
331 | data->flags = 0; | 332 | data->flags = 0; |
332 | data->int_flags = 0; | 333 | data->int_flags = 0; |
333 | data->mounted_uid = 0; | 334 | data->mounted_uid = 0; |
334 | data->wdog_pid = -1; | 335 | data->wdog_pid = NULL; |
335 | data->ncp_fd = ~0; | 336 | data->ncp_fd = ~0; |
336 | data->time_out = 10; | 337 | data->time_out = 10; |
337 | data->retry_count = 20; | 338 | data->retry_count = 20; |
@@ -343,8 +344,9 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
343 | data->mounted_vol[0] = 0; | 344 | data->mounted_vol[0] = 0; |
344 | 345 | ||
345 | while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) { | 346 | while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) { |
346 | if (optval < 0) | 347 | ret = optval; |
347 | return optval; | 348 | if (ret < 0) |
349 | goto err; | ||
348 | switch (optval) { | 350 | switch (optval) { |
349 | case 'u': | 351 | case 'u': |
350 | data->uid = optint; | 352 | data->uid = optint; |
@@ -371,7 +373,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
371 | data->flags = optint; | 373 | data->flags = optint; |
372 | break; | 374 | break; |
373 | case 'w': | 375 | case 'w': |
374 | data->wdog_pid = optint; | 376 | data->wdog_pid = find_get_pid(optint); |
375 | break; | 377 | break; |
376 | case 'n': | 378 | case 'n': |
377 | data->ncp_fd = optint; | 379 | data->ncp_fd = optint; |
@@ -380,18 +382,21 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) | |||
380 | data->info_fd = optint; | 382 | data->info_fd = optint; |
381 | break; | 383 | break; |
382 | case 'v': | 384 | case 'v': |
383 | if (optint < NCP_MOUNT_VERSION_V4) { | 385 | ret = -ECHRNG; |
384 | return -ECHRNG; | 386 | if (optint < NCP_MOUNT_VERSION_V4) |
385 | } | 387 | goto err; |
386 | if (optint > NCP_MOUNT_VERSION_V5) { | 388 | if (optint > NCP_MOUNT_VERSION_V5) |
387 | return -ECHRNG; | 389 | goto err; |
388 | } | ||
389 | version = optint; | 390 | version = optint; |
390 | break; | 391 | break; |
391 | 392 | ||
392 | } | 393 | } |
393 | } | 394 | } |
394 | return 0; | 395 | return 0; |
396 | err: | ||
397 | put_pid(data->wdog_pid); | ||
398 | data->wdog_pid = NULL; | ||
399 | return ret; | ||
395 | } | 400 | } |
396 | 401 | ||
397 | static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | 402 | static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) |
@@ -409,6 +414,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
409 | #endif | 414 | #endif |
410 | struct ncp_entry_info finfo; | 415 | struct ncp_entry_info finfo; |
411 | 416 | ||
417 | data.wdog_pid = NULL; | ||
412 | server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL); | 418 | server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL); |
413 | if (!server) | 419 | if (!server) |
414 | return -ENOMEM; | 420 | return -ENOMEM; |
@@ -425,7 +431,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
425 | data.flags = md->flags; | 431 | data.flags = md->flags; |
426 | data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; | 432 | data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; |
427 | data.mounted_uid = md->mounted_uid; | 433 | data.mounted_uid = md->mounted_uid; |
428 | data.wdog_pid = md->wdog_pid; | 434 | data.wdog_pid = find_get_pid(md->wdog_pid); |
429 | data.ncp_fd = md->ncp_fd; | 435 | data.ncp_fd = md->ncp_fd; |
430 | data.time_out = md->time_out; | 436 | data.time_out = md->time_out; |
431 | data.retry_count = md->retry_count; | 437 | data.retry_count = md->retry_count; |
@@ -445,7 +451,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
445 | data.flags = md->flags; | 451 | data.flags = md->flags; |
446 | data.int_flags = 0; | 452 | data.int_flags = 0; |
447 | data.mounted_uid = md->mounted_uid; | 453 | data.mounted_uid = md->mounted_uid; |
448 | data.wdog_pid = md->wdog_pid; | 454 | data.wdog_pid = find_get_pid(md->wdog_pid); |
449 | data.ncp_fd = md->ncp_fd; | 455 | data.ncp_fd = md->ncp_fd; |
450 | data.time_out = md->time_out; | 456 | data.time_out = md->time_out; |
451 | data.retry_count = md->retry_count; | 457 | data.retry_count = md->retry_count; |
@@ -471,7 +477,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
471 | if (!ncp_filp) | 477 | if (!ncp_filp) |
472 | goto out; | 478 | goto out; |
473 | error = -ENOTSOCK; | 479 | error = -ENOTSOCK; |
474 | sock_inode = ncp_filp->f_dentry->d_inode; | 480 | sock_inode = ncp_filp->f_path.dentry->d_inode; |
475 | if (!S_ISSOCK(sock_inode->i_mode)) | 481 | if (!S_ISSOCK(sock_inode->i_mode)) |
476 | goto out_fput; | 482 | goto out_fput; |
477 | sock = SOCKET_I(sock_inode); | 483 | sock = SOCKET_I(sock_inode); |
@@ -504,7 +510,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
504 | if (!server->info_filp) | 510 | if (!server->info_filp) |
505 | goto out_fput; | 511 | goto out_fput; |
506 | error = -ENOTSOCK; | 512 | error = -ENOTSOCK; |
507 | sock_inode = server->info_filp->f_dentry->d_inode; | 513 | sock_inode = server->info_filp->f_path.dentry->d_inode; |
508 | if (!S_ISSOCK(sock_inode->i_mode)) | 514 | if (!S_ISSOCK(sock_inode->i_mode)) |
509 | goto out_fput2; | 515 | goto out_fput2; |
510 | info_sock = SOCKET_I(sock_inode); | 516 | info_sock = SOCKET_I(sock_inode); |
@@ -577,12 +583,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
577 | server->rcv.ptr = (unsigned char*)&server->rcv.buf; | 583 | server->rcv.ptr = (unsigned char*)&server->rcv.buf; |
578 | server->rcv.len = 10; | 584 | server->rcv.len = 10; |
579 | server->rcv.state = 0; | 585 | server->rcv.state = 0; |
580 | INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc, server); | 586 | INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); |
581 | INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc, server); | 587 | INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); |
582 | sock->sk->sk_write_space = ncp_tcp_write_space; | 588 | sock->sk->sk_write_space = ncp_tcp_write_space; |
583 | } else { | 589 | } else { |
584 | INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc, server); | 590 | INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); |
585 | INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc, server); | 591 | INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); |
586 | server->timeout_tm.data = (unsigned long)server; | 592 | server->timeout_tm.data = (unsigned long)server; |
587 | server->timeout_tm.function = ncpdgram_timeout_call; | 593 | server->timeout_tm.function = ncpdgram_timeout_call; |
588 | } | 594 | } |
@@ -679,6 +685,7 @@ out_fput: | |||
679 | */ | 685 | */ |
680 | fput(ncp_filp); | 686 | fput(ncp_filp); |
681 | out: | 687 | out: |
688 | put_pid(data.wdog_pid); | ||
682 | sb->s_fs_info = NULL; | 689 | sb->s_fs_info = NULL; |
683 | kfree(server); | 690 | kfree(server); |
684 | return error; | 691 | return error; |
@@ -711,7 +718,8 @@ static void ncp_put_super(struct super_block *sb) | |||
711 | if (server->info_filp) | 718 | if (server->info_filp) |
712 | fput(server->info_filp); | 719 | fput(server->info_filp); |
713 | fput(server->ncp_filp); | 720 | fput(server->ncp_filp); |
714 | kill_proc(server->m.wdog_pid, SIGTERM, 1); | 721 | kill_pid(server->m.wdog_pid, SIGTERM, 1); |
722 | put_pid(server->m.wdog_pid); | ||
715 | 723 | ||
716 | kfree(server->priv.data); | 724 | kfree(server->priv.data); |
717 | kfree(server->auth.object_name); | 725 | kfree(server->auth.object_name); |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 589d1eac55c1..8843a83d4ef0 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -35,7 +35,7 @@ static int | |||
35 | ncp_get_fs_info(struct ncp_server * server, struct file *file, | 35 | ncp_get_fs_info(struct ncp_server * server, struct file *file, |
36 | struct ncp_fs_info __user *arg) | 36 | struct ncp_fs_info __user *arg) |
37 | { | 37 | { |
38 | struct inode *inode = file->f_dentry->d_inode; | 38 | struct inode *inode = file->f_path.dentry->d_inode; |
39 | struct ncp_fs_info info; | 39 | struct ncp_fs_info info; |
40 | 40 | ||
41 | if ((file_permission(file, MAY_WRITE) != 0) | 41 | if ((file_permission(file, MAY_WRITE) != 0) |
@@ -65,7 +65,7 @@ static int | |||
65 | ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, | 65 | ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, |
66 | struct ncp_fs_info_v2 __user * arg) | 66 | struct ncp_fs_info_v2 __user * arg) |
67 | { | 67 | { |
68 | struct inode *inode = file->f_dentry->d_inode; | 68 | struct inode *inode = file->f_path.dentry->d_inode; |
69 | struct ncp_fs_info_v2 info2; | 69 | struct ncp_fs_info_v2 info2; |
70 | 70 | ||
71 | if ((file_permission(file, MAY_WRITE) != 0) | 71 | if ((file_permission(file, MAY_WRITE) != 0) |
@@ -136,7 +136,7 @@ static int | |||
136 | ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file, | 136 | ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file, |
137 | struct compat_ncp_fs_info_v2 __user * arg) | 137 | struct compat_ncp_fs_info_v2 __user * arg) |
138 | { | 138 | { |
139 | struct inode *inode = file->f_dentry->d_inode; | 139 | struct inode *inode = file->f_path.dentry->d_inode; |
140 | struct compat_ncp_fs_info_v2 info2; | 140 | struct compat_ncp_fs_info_v2 info2; |
141 | 141 | ||
142 | if ((file_permission(file, MAY_WRITE) != 0) | 142 | if ((file_permission(file, MAY_WRITE) != 0) |
@@ -824,7 +824,7 @@ outrel: | |||
824 | #ifdef CONFIG_COMPAT | 824 | #ifdef CONFIG_COMPAT |
825 | long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 825 | long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
826 | { | 826 | { |
827 | struct inode *inode = file->f_dentry->d_inode; | 827 | struct inode *inode = file->f_path.dentry->d_inode; |
828 | int ret; | 828 | int ret; |
829 | 829 | ||
830 | lock_kernel(); | 830 | lock_kernel(); |
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c index e7d5a3097fe6..70a69115500f 100644 --- a/fs/ncpfs/mmap.c +++ b/fs/ncpfs/mmap.c | |||
@@ -29,7 +29,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area, | |||
29 | unsigned long address, int *type) | 29 | unsigned long address, int *type) |
30 | { | 30 | { |
31 | struct file *file = area->vm_file; | 31 | struct file *file = area->vm_file; |
32 | struct dentry *dentry = file->f_dentry; | 32 | struct dentry *dentry = file->f_path.dentry; |
33 | struct inode *inode = dentry->d_inode; | 33 | struct inode *inode = dentry->d_inode; |
34 | struct page* page; | 34 | struct page* page; |
35 | char *pg_addr; | 35 | char *pg_addr; |
@@ -106,7 +106,7 @@ static struct vm_operations_struct ncp_file_mmap = | |||
106 | /* This is used for a general mmap of a ncp file */ | 106 | /* This is used for a general mmap of a ncp file */ |
107 | int ncp_mmap(struct file *file, struct vm_area_struct *vma) | 107 | int ncp_mmap(struct file *file, struct vm_area_struct *vma) |
108 | { | 108 | { |
109 | struct inode *inode = file->f_dentry->d_inode; | 109 | struct inode *inode = file->f_path.dentry->d_inode; |
110 | 110 | ||
111 | DPRINTK("ncp_mmap: called\n"); | 111 | DPRINTK("ncp_mmap: called\n"); |
112 | 112 | ||
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 11c2b252ebed..e496d8b65e92 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c | |||
@@ -350,9 +350,10 @@ static void info_server(struct ncp_server *server, unsigned int id, const void * | |||
350 | } | 350 | } |
351 | } | 351 | } |
352 | 352 | ||
353 | void ncpdgram_rcv_proc(void *s) | 353 | void ncpdgram_rcv_proc(struct work_struct *work) |
354 | { | 354 | { |
355 | struct ncp_server *server = s; | 355 | struct ncp_server *server = |
356 | container_of(work, struct ncp_server, rcv.tq); | ||
356 | struct socket* sock; | 357 | struct socket* sock; |
357 | 358 | ||
358 | sock = server->ncp_sock; | 359 | sock = server->ncp_sock; |
@@ -468,9 +469,10 @@ static void __ncpdgram_timeout_proc(struct ncp_server *server) | |||
468 | } | 469 | } |
469 | } | 470 | } |
470 | 471 | ||
471 | void ncpdgram_timeout_proc(void *s) | 472 | void ncpdgram_timeout_proc(struct work_struct *work) |
472 | { | 473 | { |
473 | struct ncp_server *server = s; | 474 | struct ncp_server *server = |
475 | container_of(work, struct ncp_server, timeout_tq); | ||
474 | mutex_lock(&server->rcv.creq_mutex); | 476 | mutex_lock(&server->rcv.creq_mutex); |
475 | __ncpdgram_timeout_proc(server); | 477 | __ncpdgram_timeout_proc(server); |
476 | mutex_unlock(&server->rcv.creq_mutex); | 478 | mutex_unlock(&server->rcv.creq_mutex); |
@@ -652,18 +654,20 @@ skipdata:; | |||
652 | } | 654 | } |
653 | } | 655 | } |
654 | 656 | ||
655 | void ncp_tcp_rcv_proc(void *s) | 657 | void ncp_tcp_rcv_proc(struct work_struct *work) |
656 | { | 658 | { |
657 | struct ncp_server *server = s; | 659 | struct ncp_server *server = |
660 | container_of(work, struct ncp_server, rcv.tq); | ||
658 | 661 | ||
659 | mutex_lock(&server->rcv.creq_mutex); | 662 | mutex_lock(&server->rcv.creq_mutex); |
660 | __ncptcp_rcv_proc(server); | 663 | __ncptcp_rcv_proc(server); |
661 | mutex_unlock(&server->rcv.creq_mutex); | 664 | mutex_unlock(&server->rcv.creq_mutex); |
662 | } | 665 | } |
663 | 666 | ||
664 | void ncp_tcp_tx_proc(void *s) | 667 | void ncp_tcp_tx_proc(struct work_struct *work) |
665 | { | 668 | { |
666 | struct ncp_server *server = s; | 669 | struct ncp_server *server = |
670 | container_of(work, struct ncp_server, tx.tq); | ||
667 | 671 | ||
668 | mutex_lock(&server->rcv.creq_mutex); | 672 | mutex_lock(&server->rcv.creq_mutex); |
669 | __ncptcp_try_send(server); | 673 | __ncptcp_try_send(server); |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 5fea638743e4..23ab145daa2d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -143,7 +143,7 @@ static struct nfs_client *nfs_alloc_client(const char *hostname, | |||
143 | INIT_LIST_HEAD(&clp->cl_state_owners); | 143 | INIT_LIST_HEAD(&clp->cl_state_owners); |
144 | INIT_LIST_HEAD(&clp->cl_unused); | 144 | INIT_LIST_HEAD(&clp->cl_unused); |
145 | spin_lock_init(&clp->cl_lock); | 145 | spin_lock_init(&clp->cl_lock); |
146 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | 146 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); |
147 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | 147 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); |
148 | clp->cl_boot_time = CURRENT_TIME; | 148 | clp->cl_boot_time = CURRENT_TIME; |
149 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | 149 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b34cd16f472f..dee3d6c0f194 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -172,7 +172,7 @@ static | |||
172 | int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | 172 | int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) |
173 | { | 173 | { |
174 | struct file *file = desc->file; | 174 | struct file *file = desc->file; |
175 | struct inode *inode = file->f_dentry->d_inode; | 175 | struct inode *inode = file->f_path.dentry->d_inode; |
176 | struct rpc_cred *cred = nfs_file_cred(file); | 176 | struct rpc_cred *cred = nfs_file_cred(file); |
177 | unsigned long timestamp; | 177 | unsigned long timestamp; |
178 | int error; | 178 | int error; |
@@ -183,7 +183,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
183 | 183 | ||
184 | again: | 184 | again: |
185 | timestamp = jiffies; | 185 | timestamp = jiffies; |
186 | error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page, | 186 | error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page, |
187 | NFS_SERVER(inode)->dtsize, desc->plus); | 187 | NFS_SERVER(inode)->dtsize, desc->plus); |
188 | if (error < 0) { | 188 | if (error < 0) { |
189 | /* We requested READDIRPLUS, but the server doesn't grok it */ | 189 | /* We requested READDIRPLUS, but the server doesn't grok it */ |
@@ -308,7 +308,7 @@ int find_dirent_index(nfs_readdir_descriptor_t *desc) | |||
308 | static inline | 308 | static inline |
309 | int find_dirent_page(nfs_readdir_descriptor_t *desc) | 309 | int find_dirent_page(nfs_readdir_descriptor_t *desc) |
310 | { | 310 | { |
311 | struct inode *inode = desc->file->f_dentry->d_inode; | 311 | struct inode *inode = desc->file->f_path.dentry->d_inode; |
312 | struct page *page; | 312 | struct page *page; |
313 | int status; | 313 | int status; |
314 | 314 | ||
@@ -464,7 +464,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
464 | filldir_t filldir) | 464 | filldir_t filldir) |
465 | { | 465 | { |
466 | struct file *file = desc->file; | 466 | struct file *file = desc->file; |
467 | struct inode *inode = file->f_dentry->d_inode; | 467 | struct inode *inode = file->f_path.dentry->d_inode; |
468 | struct rpc_cred *cred = nfs_file_cred(file); | 468 | struct rpc_cred *cred = nfs_file_cred(file); |
469 | struct page *page = NULL; | 469 | struct page *page = NULL; |
470 | int status; | 470 | int status; |
@@ -477,7 +477,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
477 | status = -ENOMEM; | 477 | status = -ENOMEM; |
478 | goto out; | 478 | goto out; |
479 | } | 479 | } |
480 | desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, *desc->dir_cookie, | 480 | desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, |
481 | page, | 481 | page, |
482 | NFS_SERVER(inode)->dtsize, | 482 | NFS_SERVER(inode)->dtsize, |
483 | desc->plus); | 483 | desc->plus); |
@@ -516,7 +516,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
516 | */ | 516 | */ |
517 | static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 517 | static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
518 | { | 518 | { |
519 | struct dentry *dentry = filp->f_dentry; | 519 | struct dentry *dentry = filp->f_path.dentry; |
520 | struct inode *inode = dentry->d_inode; | 520 | struct inode *inode = dentry->d_inode; |
521 | nfs_readdir_descriptor_t my_desc, | 521 | nfs_readdir_descriptor_t my_desc, |
522 | *desc = &my_desc; | 522 | *desc = &my_desc; |
@@ -599,7 +599,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
599 | 599 | ||
600 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | 600 | loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) |
601 | { | 601 | { |
602 | mutex_lock(&filp->f_dentry->d_inode->i_mutex); | 602 | mutex_lock(&filp->f_path.dentry->d_inode->i_mutex); |
603 | switch (origin) { | 603 | switch (origin) { |
604 | case 1: | 604 | case 1: |
605 | offset += filp->f_pos; | 605 | offset += filp->f_pos; |
@@ -615,7 +615,7 @@ loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) | |||
615 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; | 615 | ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; |
616 | } | 616 | } |
617 | out: | 617 | out: |
618 | mutex_unlock(&filp->f_dentry->d_inode->i_mutex); | 618 | mutex_unlock(&filp->f_path.dentry->d_inode->i_mutex); |
619 | return offset; | 619 | return offset; |
620 | } | 620 | } |
621 | 621 | ||
@@ -1102,7 +1102,7 @@ no_open: | |||
1102 | 1102 | ||
1103 | static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) | 1103 | static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) |
1104 | { | 1104 | { |
1105 | struct dentry *parent = desc->file->f_dentry; | 1105 | struct dentry *parent = desc->file->f_path.dentry; |
1106 | struct inode *dir = parent->d_inode; | 1106 | struct inode *dir = parent->d_inode; |
1107 | struct nfs_entry *entry = desc->entry; | 1107 | struct nfs_entry *entry = desc->entry; |
1108 | struct dentry *dentry, *alias; | 1108 | struct dentry *dentry, *alias; |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index bdfabf854a51..bd21d7fde650 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -58,7 +58,7 @@ | |||
58 | 58 | ||
59 | #define NFSDBG_FACILITY NFSDBG_VFS | 59 | #define NFSDBG_FACILITY NFSDBG_VFS |
60 | 60 | ||
61 | static kmem_cache_t *nfs_direct_cachep; | 61 | static struct kmem_cache *nfs_direct_cachep; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * This represents a set of asynchronous requests that we're waiting on | 64 | * This represents a set of asynchronous requests that we're waiting on |
@@ -116,7 +116,7 @@ static inline int put_dreq(struct nfs_direct_req *dreq) | |||
116 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs) | 116 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs) |
117 | { | 117 | { |
118 | dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n", | 118 | dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n", |
119 | iocb->ki_filp->f_dentry->d_name.name, | 119 | iocb->ki_filp->f_path.dentry->d_name.name, |
120 | (long long) pos, nr_segs); | 120 | (long long) pos, nr_segs); |
121 | 121 | ||
122 | return -EINVAL; | 122 | return -EINVAL; |
@@ -143,7 +143,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) | |||
143 | { | 143 | { |
144 | struct nfs_direct_req *dreq; | 144 | struct nfs_direct_req *dreq; |
145 | 145 | ||
146 | dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); | 146 | dreq = kmem_cache_alloc(nfs_direct_cachep, GFP_KERNEL); |
147 | if (!dreq) | 147 | if (!dreq) |
148 | return NULL; | 148 | return NULL; |
149 | 149 | ||
@@ -307,9 +307,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
307 | 307 | ||
308 | data->task.tk_cookie = (unsigned long) inode; | 308 | data->task.tk_cookie = (unsigned long) inode; |
309 | 309 | ||
310 | lock_kernel(); | ||
311 | rpc_execute(&data->task); | 310 | rpc_execute(&data->task); |
312 | unlock_kernel(); | ||
313 | 311 | ||
314 | dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", | 312 | dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", |
315 | data->task.tk_pid, | 313 | data->task.tk_pid, |
@@ -475,9 +473,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
475 | 473 | ||
476 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); | 474 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); |
477 | 475 | ||
478 | lock_kernel(); | ||
479 | rpc_execute(&data->task); | 476 | rpc_execute(&data->task); |
480 | unlock_kernel(); | ||
481 | } | 477 | } |
482 | 478 | ||
483 | static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) | 479 | static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) |
@@ -641,9 +637,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
641 | data->task.tk_priority = RPC_PRIORITY_NORMAL; | 637 | data->task.tk_priority = RPC_PRIORITY_NORMAL; |
642 | data->task.tk_cookie = (unsigned long) inode; | 638 | data->task.tk_cookie = (unsigned long) inode; |
643 | 639 | ||
644 | lock_kernel(); | ||
645 | rpc_execute(&data->task); | 640 | rpc_execute(&data->task); |
646 | unlock_kernel(); | ||
647 | 641 | ||
648 | dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", | 642 | dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", |
649 | data->task.tk_pid, | 643 | data->task.tk_pid, |
@@ -740,8 +734,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
740 | size_t count = iov[0].iov_len; | 734 | size_t count = iov[0].iov_len; |
741 | 735 | ||
742 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", | 736 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", |
743 | file->f_dentry->d_parent->d_name.name, | 737 | file->f_path.dentry->d_parent->d_name.name, |
744 | file->f_dentry->d_name.name, | 738 | file->f_path.dentry->d_name.name, |
745 | (unsigned long) count, (long long) pos); | 739 | (unsigned long) count, (long long) pos); |
746 | 740 | ||
747 | if (nr_segs != 1) | 741 | if (nr_segs != 1) |
@@ -804,8 +798,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
804 | size_t count = iov[0].iov_len; | 798 | size_t count = iov[0].iov_len; |
805 | 799 | ||
806 | dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", | 800 | dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", |
807 | file->f_dentry->d_parent->d_name.name, | 801 | file->f_path.dentry->d_parent->d_name.name, |
808 | file->f_dentry->d_name.name, | 802 | file->f_path.dentry->d_name.name, |
809 | (unsigned long) count, (long long) pos); | 803 | (unsigned long) count, (long long) pos); |
810 | 804 | ||
811 | if (nr_segs != 1) | 805 | if (nr_segs != 1) |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cc93865cea93..fab20d06d936 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -176,7 +176,7 @@ static int | |||
176 | nfs_file_flush(struct file *file, fl_owner_t id) | 176 | nfs_file_flush(struct file *file, fl_owner_t id) |
177 | { | 177 | { |
178 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 178 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
179 | struct inode *inode = file->f_dentry->d_inode; | 179 | struct inode *inode = file->f_path.dentry->d_inode; |
180 | int status; | 180 | int status; |
181 | 181 | ||
182 | dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); | 182 | dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); |
@@ -201,7 +201,7 @@ static ssize_t | |||
201 | nfs_file_read(struct kiocb *iocb, const struct iovec *iov, | 201 | nfs_file_read(struct kiocb *iocb, const struct iovec *iov, |
202 | unsigned long nr_segs, loff_t pos) | 202 | unsigned long nr_segs, loff_t pos) |
203 | { | 203 | { |
204 | struct dentry * dentry = iocb->ki_filp->f_dentry; | 204 | struct dentry * dentry = iocb->ki_filp->f_path.dentry; |
205 | struct inode * inode = dentry->d_inode; | 205 | struct inode * inode = dentry->d_inode; |
206 | ssize_t result; | 206 | ssize_t result; |
207 | size_t count = iov_length(iov, nr_segs); | 207 | size_t count = iov_length(iov, nr_segs); |
@@ -226,7 +226,7 @@ static ssize_t | |||
226 | nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, | 226 | nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, |
227 | read_actor_t actor, void *target) | 227 | read_actor_t actor, void *target) |
228 | { | 228 | { |
229 | struct dentry *dentry = filp->f_dentry; | 229 | struct dentry *dentry = filp->f_path.dentry; |
230 | struct inode *inode = dentry->d_inode; | 230 | struct inode *inode = dentry->d_inode; |
231 | ssize_t res; | 231 | ssize_t res; |
232 | 232 | ||
@@ -243,7 +243,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, | |||
243 | static int | 243 | static int |
244 | nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | 244 | nfs_file_mmap(struct file * file, struct vm_area_struct * vma) |
245 | { | 245 | { |
246 | struct dentry *dentry = file->f_dentry; | 246 | struct dentry *dentry = file->f_path.dentry; |
247 | struct inode *inode = dentry->d_inode; | 247 | struct inode *inode = dentry->d_inode; |
248 | int status; | 248 | int status; |
249 | 249 | ||
@@ -307,28 +307,27 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse | |||
307 | 307 | ||
308 | static void nfs_invalidate_page(struct page *page, unsigned long offset) | 308 | static void nfs_invalidate_page(struct page *page, unsigned long offset) |
309 | { | 309 | { |
310 | struct inode *inode = page->mapping->host; | 310 | if (offset != 0) |
311 | 311 | return; | |
312 | /* Cancel any unstarted writes on this page */ | 312 | /* Cancel any unstarted writes on this page */ |
313 | if (offset == 0) | 313 | nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE); |
314 | nfs_sync_inode_wait(inode, page->index, 1, FLUSH_INVALIDATE); | ||
315 | } | 314 | } |
316 | 315 | ||
317 | static int nfs_release_page(struct page *page, gfp_t gfp) | 316 | static int nfs_release_page(struct page *page, gfp_t gfp) |
318 | { | 317 | { |
319 | if (gfp & __GFP_FS) | 318 | /* If PagePrivate() is set, then the page is not freeable */ |
320 | return !nfs_wb_page(page->mapping->host, page); | 319 | return 0; |
321 | else | 320 | } |
322 | /* | 321 | |
323 | * Avoid deadlock on nfs_wait_on_request(). | 322 | static int nfs_launder_page(struct page *page) |
324 | */ | 323 | { |
325 | return 0; | 324 | return nfs_wb_page(page->mapping->host, page); |
326 | } | 325 | } |
327 | 326 | ||
328 | const struct address_space_operations nfs_file_aops = { | 327 | const struct address_space_operations nfs_file_aops = { |
329 | .readpage = nfs_readpage, | 328 | .readpage = nfs_readpage, |
330 | .readpages = nfs_readpages, | 329 | .readpages = nfs_readpages, |
331 | .set_page_dirty = __set_page_dirty_nobuffers, | 330 | .set_page_dirty = nfs_set_page_dirty, |
332 | .writepage = nfs_writepage, | 331 | .writepage = nfs_writepage, |
333 | .writepages = nfs_writepages, | 332 | .writepages = nfs_writepages, |
334 | .prepare_write = nfs_prepare_write, | 333 | .prepare_write = nfs_prepare_write, |
@@ -338,12 +337,13 @@ const struct address_space_operations nfs_file_aops = { | |||
338 | #ifdef CONFIG_NFS_DIRECTIO | 337 | #ifdef CONFIG_NFS_DIRECTIO |
339 | .direct_IO = nfs_direct_IO, | 338 | .direct_IO = nfs_direct_IO, |
340 | #endif | 339 | #endif |
340 | .launder_page = nfs_launder_page, | ||
341 | }; | 341 | }; |
342 | 342 | ||
343 | static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, | 343 | static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, |
344 | unsigned long nr_segs, loff_t pos) | 344 | unsigned long nr_segs, loff_t pos) |
345 | { | 345 | { |
346 | struct dentry * dentry = iocb->ki_filp->f_dentry; | 346 | struct dentry * dentry = iocb->ki_filp->f_path.dentry; |
347 | struct inode * inode = dentry->d_inode; | 347 | struct inode * inode = dentry->d_inode; |
348 | ssize_t result; | 348 | ssize_t result; |
349 | size_t count = iov_length(iov, nr_segs); | 349 | size_t count = iov_length(iov, nr_segs); |
@@ -375,6 +375,12 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
375 | 375 | ||
376 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); | 376 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); |
377 | result = generic_file_aio_write(iocb, iov, nr_segs, pos); | 377 | result = generic_file_aio_write(iocb, iov, nr_segs, pos); |
378 | /* Return error values for O_SYNC and IS_SYNC() */ | ||
379 | if (result >= 0 && (IS_SYNC(inode) || (iocb->ki_filp->f_flags & O_SYNC))) { | ||
380 | int err = nfs_fsync(iocb->ki_filp, dentry, 1); | ||
381 | if (err < 0) | ||
382 | result = err; | ||
383 | } | ||
378 | out: | 384 | out: |
379 | return result; | 385 | return result; |
380 | 386 | ||
@@ -529,8 +535,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
529 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | 535 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) |
530 | { | 536 | { |
531 | dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", | 537 | dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", |
532 | filp->f_dentry->d_inode->i_sb->s_id, | 538 | filp->f_path.dentry->d_inode->i_sb->s_id, |
533 | filp->f_dentry->d_inode->i_ino, | 539 | filp->f_path.dentry->d_inode->i_ino, |
534 | fl->fl_type, fl->fl_flags); | 540 | fl->fl_type, fl->fl_flags); |
535 | 541 | ||
536 | /* | 542 | /* |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 20c6f39ea38a..8391bd7a83ce 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/nfs_idmap.h> | 31 | #include <linux/nfs_idmap.h> |
32 | #include <linux/vfs.h> | 32 | #include <linux/vfs.h> |
33 | #include <linux/namei.h> | 33 | #include <linux/namei.h> |
34 | #include <linux/namespace.h> | 34 | #include <linux/mnt_namespace.h> |
35 | #include <linux/security.h> | 35 | #include <linux/security.h> |
36 | 36 | ||
37 | #include <asm/system.h> | 37 | #include <asm/system.h> |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 82ad7110a1c0..9d4a6b2d1996 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -377,7 +377,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, | |||
377 | static ssize_t | 377 | static ssize_t |
378 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | 378 | idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) |
379 | { | 379 | { |
380 | struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); | 380 | struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); |
381 | struct idmap *idmap = (struct idmap *)rpci->private; | 381 | struct idmap *idmap = (struct idmap *)rpci->private; |
382 | struct idmap_msg im_in, *im = &idmap->idmap_im; | 382 | struct idmap_msg im_in, *im = &idmap->idmap_im; |
383 | struct idmap_hashtable *h; | 383 | struct idmap_hashtable *h; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 08cc4c5919ab..63e470279309 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -55,7 +55,7 @@ static int nfs_update_inode(struct inode *, struct nfs_fattr *); | |||
55 | 55 | ||
56 | static void nfs_zap_acl_cache(struct inode *); | 56 | static void nfs_zap_acl_cache(struct inode *); |
57 | 57 | ||
58 | static kmem_cache_t * nfs_inode_cachep; | 58 | static struct kmem_cache * nfs_inode_cachep; |
59 | 59 | ||
60 | static inline unsigned long | 60 | static inline unsigned long |
61 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) | 61 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) |
@@ -422,7 +422,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
422 | int err; | 422 | int err; |
423 | 423 | ||
424 | /* Flush out writes to the server in order to update c/mtime */ | 424 | /* Flush out writes to the server in order to update c/mtime */ |
425 | nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT); | 425 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); |
426 | 426 | ||
427 | /* | 427 | /* |
428 | * We may force a getattr if the user cares about atime. | 428 | * We may force a getattr if the user cares about atime. |
@@ -496,7 +496,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
496 | */ | 496 | */ |
497 | static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | 497 | static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) |
498 | { | 498 | { |
499 | struct inode *inode = filp->f_dentry->d_inode; | 499 | struct inode *inode = filp->f_path.dentry->d_inode; |
500 | struct nfs_inode *nfsi = NFS_I(inode); | 500 | struct nfs_inode *nfsi = NFS_I(inode); |
501 | 501 | ||
502 | filp->private_data = get_nfs_open_context(ctx); | 502 | filp->private_data = get_nfs_open_context(ctx); |
@@ -528,7 +528,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c | |||
528 | 528 | ||
529 | static void nfs_file_clear_open_context(struct file *filp) | 529 | static void nfs_file_clear_open_context(struct file *filp) |
530 | { | 530 | { |
531 | struct inode *inode = filp->f_dentry->d_inode; | 531 | struct inode *inode = filp->f_path.dentry->d_inode; |
532 | struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; | 532 | struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; |
533 | 533 | ||
534 | if (ctx) { | 534 | if (ctx) { |
@@ -551,7 +551,7 @@ int nfs_open(struct inode *inode, struct file *filp) | |||
551 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); | 551 | cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); |
552 | if (IS_ERR(cred)) | 552 | if (IS_ERR(cred)) |
553 | return PTR_ERR(cred); | 553 | return PTR_ERR(cred); |
554 | ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred); | 554 | ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred); |
555 | put_rpccred(cred); | 555 | put_rpccred(cred); |
556 | if (ctx == NULL) | 556 | if (ctx == NULL) |
557 | return -ENOMEM; | 557 | return -ENOMEM; |
@@ -1080,7 +1080,7 @@ void nfs4_clear_inode(struct inode *inode) | |||
1080 | struct inode *nfs_alloc_inode(struct super_block *sb) | 1080 | struct inode *nfs_alloc_inode(struct super_block *sb) |
1081 | { | 1081 | { |
1082 | struct nfs_inode *nfsi; | 1082 | struct nfs_inode *nfsi; |
1083 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); | 1083 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL); |
1084 | if (!nfsi) | 1084 | if (!nfsi) |
1085 | return NULL; | 1085 | return NULL; |
1086 | nfsi->flags = 0UL; | 1086 | nfsi->flags = 0UL; |
@@ -1111,7 +1111,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) | |||
1111 | #endif | 1111 | #endif |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 1114 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
1115 | { | 1115 | { |
1116 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; | 1116 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; |
1117 | 1117 | ||
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index d205466233f6..a28f6ce2e131 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -217,3 +217,21 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) | |||
217 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) | 217 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) |
218 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 218 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
219 | } | 219 | } |
220 | |||
221 | /* | ||
222 | * Determine the number of bytes of data the page contains | ||
223 | */ | ||
224 | static inline | ||
225 | unsigned int nfs_page_length(struct page *page) | ||
226 | { | ||
227 | loff_t i_size = i_size_read(page->mapping->host); | ||
228 | |||
229 | if (i_size > 0) { | ||
230 | pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; | ||
231 | if (page->index < end_index) | ||
232 | return PAGE_CACHE_SIZE; | ||
233 | if (page->index == end_index) | ||
234 | return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1; | ||
235 | } | ||
236 | return 0; | ||
237 | } | ||
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index ec1114b33d89..371b804e7cc8 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -18,10 +18,10 @@ | |||
18 | 18 | ||
19 | #define NFSDBG_FACILITY NFSDBG_VFS | 19 | #define NFSDBG_FACILITY NFSDBG_VFS |
20 | 20 | ||
21 | static void nfs_expire_automounts(void *list); | 21 | static void nfs_expire_automounts(struct work_struct *work); |
22 | 22 | ||
23 | LIST_HEAD(nfs_automount_list); | 23 | LIST_HEAD(nfs_automount_list); |
24 | static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); | 24 | static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); |
25 | int nfs_mountpoint_expiry_timeout = 500 * HZ; | 25 | int nfs_mountpoint_expiry_timeout = 500 * HZ; |
26 | 26 | ||
27 | static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, | 27 | static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, |
@@ -164,9 +164,9 @@ struct inode_operations nfs_referral_inode_operations = { | |||
164 | .follow_link = nfs_follow_mountpoint, | 164 | .follow_link = nfs_follow_mountpoint, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static void nfs_expire_automounts(void *data) | 167 | static void nfs_expire_automounts(struct work_struct *work) |
168 | { | 168 | { |
169 | struct list_head *list = (struct list_head *)data; | 169 | struct list_head *list = &nfs_automount_list; |
170 | 170 | ||
171 | mark_mounts_for_expiry(list); | 171 | mark_mounts_for_expiry(list); |
172 | if (!list_empty(list)) | 172 | if (!list_empty(list)) |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index e5f128ffc32d..acd8fe9762d3 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -276,51 +276,6 @@ static int nfs3_proc_read(struct nfs_read_data *rdata) | |||
276 | return status; | 276 | return status; |
277 | } | 277 | } |
278 | 278 | ||
279 | static int nfs3_proc_write(struct nfs_write_data *wdata) | ||
280 | { | ||
281 | int rpcflags = wdata->flags; | ||
282 | struct inode * inode = wdata->inode; | ||
283 | struct nfs_fattr * fattr = wdata->res.fattr; | ||
284 | struct rpc_message msg = { | ||
285 | .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE], | ||
286 | .rpc_argp = &wdata->args, | ||
287 | .rpc_resp = &wdata->res, | ||
288 | .rpc_cred = wdata->cred, | ||
289 | }; | ||
290 | int status; | ||
291 | |||
292 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
293 | (long long) wdata->args.offset); | ||
294 | nfs_fattr_init(fattr); | ||
295 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); | ||
296 | if (status >= 0) | ||
297 | nfs_post_op_update_inode(inode, fattr); | ||
298 | dprintk("NFS reply write: %d\n", status); | ||
299 | return status < 0? status : wdata->res.count; | ||
300 | } | ||
301 | |||
302 | static int nfs3_proc_commit(struct nfs_write_data *cdata) | ||
303 | { | ||
304 | struct inode * inode = cdata->inode; | ||
305 | struct nfs_fattr * fattr = cdata->res.fattr; | ||
306 | struct rpc_message msg = { | ||
307 | .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT], | ||
308 | .rpc_argp = &cdata->args, | ||
309 | .rpc_resp = &cdata->res, | ||
310 | .rpc_cred = cdata->cred, | ||
311 | }; | ||
312 | int status; | ||
313 | |||
314 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, | ||
315 | (long long) cdata->args.offset); | ||
316 | nfs_fattr_init(fattr); | ||
317 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | ||
318 | if (status >= 0) | ||
319 | nfs_post_op_update_inode(inode, fattr); | ||
320 | dprintk("NFS reply commit: %d\n", status); | ||
321 | return status; | ||
322 | } | ||
323 | |||
324 | /* | 279 | /* |
325 | * Create a regular file. | 280 | * Create a regular file. |
326 | * For now, we don't implement O_EXCL. | 281 | * For now, we don't implement O_EXCL. |
@@ -369,7 +324,7 @@ again: | |||
369 | 324 | ||
370 | /* If the server doesn't support the exclusive creation semantics, | 325 | /* If the server doesn't support the exclusive creation semantics, |
371 | * try again with simple 'guarded' mode. */ | 326 | * try again with simple 'guarded' mode. */ |
372 | if (status == NFSERR_NOTSUPP) { | 327 | if (status == -ENOTSUPP) { |
373 | switch (arg.createmode) { | 328 | switch (arg.createmode) { |
374 | case NFS3_CREATE_EXCLUSIVE: | 329 | case NFS3_CREATE_EXCLUSIVE: |
375 | arg.createmode = NFS3_CREATE_GUARDED; | 330 | arg.createmode = NFS3_CREATE_GUARDED; |
@@ -690,8 +645,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
690 | }; | 645 | }; |
691 | int status; | 646 | int status; |
692 | 647 | ||
693 | lock_kernel(); | ||
694 | |||
695 | if (plus) | 648 | if (plus) |
696 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; | 649 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; |
697 | 650 | ||
@@ -702,7 +655,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
702 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 655 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
703 | nfs_refresh_inode(dir, &dir_attr); | 656 | nfs_refresh_inode(dir, &dir_attr); |
704 | dprintk("NFS reply readdir: %d\n", status); | 657 | dprintk("NFS reply readdir: %d\n", status); |
705 | unlock_kernel(); | ||
706 | return status; | 658 | return status; |
707 | } | 659 | } |
708 | 660 | ||
@@ -889,7 +841,7 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how) | |||
889 | static int | 841 | static int |
890 | nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) | 842 | nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) |
891 | { | 843 | { |
892 | return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); | 844 | return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); |
893 | } | 845 | } |
894 | 846 | ||
895 | const struct nfs_rpc_ops nfs_v3_clientops = { | 847 | const struct nfs_rpc_ops nfs_v3_clientops = { |
@@ -904,8 +856,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { | |||
904 | .access = nfs3_proc_access, | 856 | .access = nfs3_proc_access, |
905 | .readlink = nfs3_proc_readlink, | 857 | .readlink = nfs3_proc_readlink, |
906 | .read = nfs3_proc_read, | 858 | .read = nfs3_proc_read, |
907 | .write = nfs3_proc_write, | ||
908 | .commit = nfs3_proc_commit, | ||
909 | .create = nfs3_proc_create, | 859 | .create = nfs3_proc_create, |
910 | .remove = nfs3_proc_remove, | 860 | .remove = nfs3_proc_remove, |
911 | .unlink_setup = nfs3_proc_unlink_setup, | 861 | .unlink_setup = nfs3_proc_unlink_setup, |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6f346677332d..c26cd978c7cc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -185,7 +185,7 @@ extern const u32 nfs4_fs_locations_bitmap[2]; | |||
185 | extern void nfs4_schedule_state_renewal(struct nfs_client *); | 185 | extern void nfs4_schedule_state_renewal(struct nfs_client *); |
186 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); | 186 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); |
187 | extern void nfs4_kill_renewd(struct nfs_client *); | 187 | extern void nfs4_kill_renewd(struct nfs_client *); |
188 | extern void nfs4_renew_state(void *); | 188 | extern void nfs4_renew_state(struct work_struct *); |
189 | 189 | ||
190 | /* nfs4state.c */ | 190 | /* nfs4state.c */ |
191 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); | 191 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8118036cc449..b3fd29baadc3 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -636,7 +636,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
636 | smp_wmb(); | 636 | smp_wmb(); |
637 | } else | 637 | } else |
638 | status = data->rpc_status; | 638 | status = data->rpc_status; |
639 | rpc_release_task(task); | 639 | rpc_put_task(task); |
640 | return status; | 640 | return status; |
641 | } | 641 | } |
642 | 642 | ||
@@ -742,7 +742,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
742 | smp_wmb(); | 742 | smp_wmb(); |
743 | } else | 743 | } else |
744 | status = data->rpc_status; | 744 | status = data->rpc_status; |
745 | rpc_release_task(task); | 745 | rpc_put_task(task); |
746 | if (status != 0) | 746 | if (status != 0) |
747 | return status; | 747 | return status; |
748 | 748 | ||
@@ -1775,89 +1775,6 @@ static int nfs4_proc_read(struct nfs_read_data *rdata) | |||
1775 | return err; | 1775 | return err; |
1776 | } | 1776 | } |
1777 | 1777 | ||
1778 | static int _nfs4_proc_write(struct nfs_write_data *wdata) | ||
1779 | { | ||
1780 | int rpcflags = wdata->flags; | ||
1781 | struct inode *inode = wdata->inode; | ||
1782 | struct nfs_fattr *fattr = wdata->res.fattr; | ||
1783 | struct nfs_server *server = NFS_SERVER(inode); | ||
1784 | struct rpc_message msg = { | ||
1785 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], | ||
1786 | .rpc_argp = &wdata->args, | ||
1787 | .rpc_resp = &wdata->res, | ||
1788 | .rpc_cred = wdata->cred, | ||
1789 | }; | ||
1790 | int status; | ||
1791 | |||
1792 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
1793 | (long long) wdata->args.offset); | ||
1794 | |||
1795 | wdata->args.bitmask = server->attr_bitmask; | ||
1796 | wdata->res.server = server; | ||
1797 | wdata->timestamp = jiffies; | ||
1798 | nfs_fattr_init(fattr); | ||
1799 | status = rpc_call_sync(server->client, &msg, rpcflags); | ||
1800 | dprintk("NFS reply write: %d\n", status); | ||
1801 | if (status < 0) | ||
1802 | return status; | ||
1803 | renew_lease(server, wdata->timestamp); | ||
1804 | nfs_post_op_update_inode(inode, fattr); | ||
1805 | return wdata->res.count; | ||
1806 | } | ||
1807 | |||
1808 | static int nfs4_proc_write(struct nfs_write_data *wdata) | ||
1809 | { | ||
1810 | struct nfs4_exception exception = { }; | ||
1811 | int err; | ||
1812 | do { | ||
1813 | err = nfs4_handle_exception(NFS_SERVER(wdata->inode), | ||
1814 | _nfs4_proc_write(wdata), | ||
1815 | &exception); | ||
1816 | } while (exception.retry); | ||
1817 | return err; | ||
1818 | } | ||
1819 | |||
1820 | static int _nfs4_proc_commit(struct nfs_write_data *cdata) | ||
1821 | { | ||
1822 | struct inode *inode = cdata->inode; | ||
1823 | struct nfs_fattr *fattr = cdata->res.fattr; | ||
1824 | struct nfs_server *server = NFS_SERVER(inode); | ||
1825 | struct rpc_message msg = { | ||
1826 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], | ||
1827 | .rpc_argp = &cdata->args, | ||
1828 | .rpc_resp = &cdata->res, | ||
1829 | .rpc_cred = cdata->cred, | ||
1830 | }; | ||
1831 | int status; | ||
1832 | |||
1833 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, | ||
1834 | (long long) cdata->args.offset); | ||
1835 | |||
1836 | cdata->args.bitmask = server->attr_bitmask; | ||
1837 | cdata->res.server = server; | ||
1838 | cdata->timestamp = jiffies; | ||
1839 | nfs_fattr_init(fattr); | ||
1840 | status = rpc_call_sync(server->client, &msg, 0); | ||
1841 | if (status >= 0) | ||
1842 | renew_lease(server, cdata->timestamp); | ||
1843 | dprintk("NFS reply commit: %d\n", status); | ||
1844 | if (status >= 0) | ||
1845 | nfs_post_op_update_inode(inode, fattr); | ||
1846 | return status; | ||
1847 | } | ||
1848 | |||
1849 | static int nfs4_proc_commit(struct nfs_write_data *cdata) | ||
1850 | { | ||
1851 | struct nfs4_exception exception = { }; | ||
1852 | int err; | ||
1853 | do { | ||
1854 | err = nfs4_handle_exception(NFS_SERVER(cdata->inode), | ||
1855 | _nfs4_proc_commit(cdata), | ||
1856 | &exception); | ||
1857 | } while (exception.retry); | ||
1858 | return err; | ||
1859 | } | ||
1860 | |||
1861 | /* | 1778 | /* |
1862 | * Got race? | 1779 | * Got race? |
1863 | * We will need to arrange for the VFS layer to provide an atomic open. | 1780 | * We will need to arrange for the VFS layer to provide an atomic open. |
@@ -1960,7 +1877,7 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, | |||
1960 | struct nfs_server *server = NFS_SERVER(dir->d_inode); | 1877 | struct nfs_server *server = NFS_SERVER(dir->d_inode); |
1961 | struct unlink_desc *up; | 1878 | struct unlink_desc *up; |
1962 | 1879 | ||
1963 | up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL); | 1880 | up = kmalloc(sizeof(*up), GFP_KERNEL); |
1964 | if (!up) | 1881 | if (!up) |
1965 | return -ENOMEM; | 1882 | return -ENOMEM; |
1966 | 1883 | ||
@@ -2223,13 +2140,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2223 | dentry->d_parent->d_name.name, | 2140 | dentry->d_parent->d_name.name, |
2224 | dentry->d_name.name, | 2141 | dentry->d_name.name, |
2225 | (unsigned long long)cookie); | 2142 | (unsigned long long)cookie); |
2226 | lock_kernel(); | ||
2227 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 2143 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); |
2228 | res.pgbase = args.pgbase; | 2144 | res.pgbase = args.pgbase; |
2229 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 2145 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
2230 | if (status == 0) | 2146 | if (status == 0) |
2231 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 2147 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); |
2232 | unlock_kernel(); | ||
2233 | dprintk("%s: returns %d\n", __FUNCTION__, status); | 2148 | dprintk("%s: returns %d\n", __FUNCTION__, status); |
2234 | return status; | 2149 | return status; |
2235 | } | 2150 | } |
@@ -3067,7 +2982,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
3067 | if (status == 0) | 2982 | if (status == 0) |
3068 | nfs_post_op_update_inode(inode, &data->fattr); | 2983 | nfs_post_op_update_inode(inode, &data->fattr); |
3069 | } | 2984 | } |
3070 | rpc_release_task(task); | 2985 | rpc_put_task(task); |
3071 | return status; | 2986 | return status; |
3072 | } | 2987 | } |
3073 | 2988 | ||
@@ -3314,7 +3229,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * | |||
3314 | if (IS_ERR(task)) | 3229 | if (IS_ERR(task)) |
3315 | goto out; | 3230 | goto out; |
3316 | status = nfs4_wait_for_completion_rpc_task(task); | 3231 | status = nfs4_wait_for_completion_rpc_task(task); |
3317 | rpc_release_task(task); | 3232 | rpc_put_task(task); |
3318 | out: | 3233 | out: |
3319 | return status; | 3234 | return status; |
3320 | } | 3235 | } |
@@ -3430,7 +3345,7 @@ static void nfs4_lock_release(void *calldata) | |||
3430 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, | 3345 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, |
3431 | data->arg.lock_seqid); | 3346 | data->arg.lock_seqid); |
3432 | if (!IS_ERR(task)) | 3347 | if (!IS_ERR(task)) |
3433 | rpc_release_task(task); | 3348 | rpc_put_task(task); |
3434 | dprintk("%s: cancelling lock!\n", __FUNCTION__); | 3349 | dprintk("%s: cancelling lock!\n", __FUNCTION__); |
3435 | } else | 3350 | } else |
3436 | nfs_free_seqid(data->arg.lock_seqid); | 3351 | nfs_free_seqid(data->arg.lock_seqid); |
@@ -3472,7 +3387,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
3472 | ret = -EAGAIN; | 3387 | ret = -EAGAIN; |
3473 | } else | 3388 | } else |
3474 | data->cancelled = 1; | 3389 | data->cancelled = 1; |
3475 | rpc_release_task(task); | 3390 | rpc_put_task(task); |
3476 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); | 3391 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); |
3477 | return ret; | 3392 | return ret; |
3478 | } | 3393 | } |
@@ -3732,8 +3647,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
3732 | .access = nfs4_proc_access, | 3647 | .access = nfs4_proc_access, |
3733 | .readlink = nfs4_proc_readlink, | 3648 | .readlink = nfs4_proc_readlink, |
3734 | .read = nfs4_proc_read, | 3649 | .read = nfs4_proc_read, |
3735 | .write = nfs4_proc_write, | ||
3736 | .commit = nfs4_proc_commit, | ||
3737 | .create = nfs4_proc_create, | 3650 | .create = nfs4_proc_create, |
3738 | .remove = nfs4_proc_remove, | 3651 | .remove = nfs4_proc_remove, |
3739 | .unlink_setup = nfs4_proc_unlink_setup, | 3652 | .unlink_setup = nfs4_proc_unlink_setup, |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 7b6df1852e75..823298561c0a 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -59,9 +59,10 @@ | |||
59 | #define NFSDBG_FACILITY NFSDBG_PROC | 59 | #define NFSDBG_FACILITY NFSDBG_PROC |
60 | 60 | ||
61 | void | 61 | void |
62 | nfs4_renew_state(void *data) | 62 | nfs4_renew_state(struct work_struct *work) |
63 | { | 63 | { |
64 | struct nfs_client *clp = (struct nfs_client *)data; | 64 | struct nfs_client *clp = |
65 | container_of(work, struct nfs_client, cl_renewd.work); | ||
65 | struct rpc_cred *cred; | 66 | struct rpc_cred *cred; |
66 | long lease, timeout; | 67 | long lease, timeout; |
67 | unsigned long last, now; | 68 | unsigned long last, now; |
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 8dfefe41a8da..75f819dc0255 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -98,7 +98,7 @@ | |||
98 | static char nfs_root_name[256] __initdata = ""; | 98 | static char nfs_root_name[256] __initdata = ""; |
99 | 99 | ||
100 | /* Address of NFS server */ | 100 | /* Address of NFS server */ |
101 | static __u32 servaddr __initdata = 0; | 101 | static __be32 servaddr __initdata = 0; |
102 | 102 | ||
103 | /* Name of directory to mount */ | 103 | /* Name of directory to mount */ |
104 | static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; | 104 | static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; |
@@ -327,7 +327,7 @@ static int __init root_nfs_name(char *name) | |||
327 | */ | 327 | */ |
328 | static int __init root_nfs_addr(void) | 328 | static int __init root_nfs_addr(void) |
329 | { | 329 | { |
330 | if ((servaddr = root_server_addr) == INADDR_NONE) { | 330 | if ((servaddr = root_server_addr) == htonl(INADDR_NONE)) { |
331 | printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); | 331 | printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); |
332 | return -1; | 332 | return -1; |
333 | } | 333 | } |
@@ -411,7 +411,7 @@ __setup("nfsroot=", nfs_root_setup); | |||
411 | * Construct sockaddr_in from address and port number. | 411 | * Construct sockaddr_in from address and port number. |
412 | */ | 412 | */ |
413 | static inline void | 413 | static inline void |
414 | set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port) | 414 | set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port) |
415 | { | 415 | { |
416 | sin->sin_family = AF_INET; | 416 | sin->sin_family = AF_INET; |
417 | sin->sin_addr.s_addr = addr; | 417 | sin->sin_addr.s_addr = addr; |
@@ -468,14 +468,13 @@ static int __init root_nfs_ports(void) | |||
468 | dprintk("Root-NFS: Portmapper on server returned %d " | 468 | dprintk("Root-NFS: Portmapper on server returned %d " |
469 | "as nfsd port\n", port); | 469 | "as nfsd port\n", port); |
470 | } | 470 | } |
471 | nfs_port = htons(nfs_port); | ||
472 | 471 | ||
473 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { | 472 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { |
474 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " | 473 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " |
475 | "number from server, using default\n"); | 474 | "number from server, using default\n"); |
476 | port = mountd_port; | 475 | port = mountd_port; |
477 | } | 476 | } |
478 | mount_port = htons(port); | 477 | mount_port = port; |
479 | dprintk("Root-NFS: mountd port is %d\n", port); | 478 | dprintk("Root-NFS: mountd port is %d\n", port); |
480 | 479 | ||
481 | return 0; | 480 | return 0; |
@@ -496,7 +495,7 @@ static int __init root_nfs_get_handle(void) | |||
496 | int version = (nfs_data.flags & NFS_MOUNT_VER3) ? | 495 | int version = (nfs_data.flags & NFS_MOUNT_VER3) ? |
497 | NFS_MNT3_VERSION : NFS_MNT_VERSION; | 496 | NFS_MNT3_VERSION : NFS_MNT_VERSION; |
498 | 497 | ||
499 | set_sockaddr(&sin, servaddr, mount_port); | 498 | set_sockaddr(&sin, servaddr, htons(mount_port)); |
500 | status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol); | 499 | status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol); |
501 | if (status < 0) | 500 | if (status < 0) |
502 | printk(KERN_ERR "Root-NFS: Server returned error %d " | 501 | printk(KERN_ERR "Root-NFS: Server returned error %d " |
@@ -519,6 +518,6 @@ void * __init nfs_root_data(void) | |||
519 | || root_nfs_ports() < 0 | 518 | || root_nfs_ports() < 0 |
520 | || root_nfs_get_handle() < 0) | 519 | || root_nfs_get_handle() < 0) |
521 | return NULL; | 520 | return NULL; |
522 | set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port); | 521 | set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port)); |
523 | return (void*)&nfs_data; | 522 | return (void*)&nfs_data; |
524 | } | 523 | } |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 829af323f288..ca4b1d4ff42b 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -17,16 +17,17 @@ | |||
17 | #include <linux/nfs_page.h> | 17 | #include <linux/nfs_page.h> |
18 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
19 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
20 | #include <linux/writeback.h> | ||
20 | 21 | ||
21 | #define NFS_PARANOIA 1 | 22 | #define NFS_PARANOIA 1 |
22 | 23 | ||
23 | static kmem_cache_t *nfs_page_cachep; | 24 | static struct kmem_cache *nfs_page_cachep; |
24 | 25 | ||
25 | static inline struct nfs_page * | 26 | static inline struct nfs_page * |
26 | nfs_page_alloc(void) | 27 | nfs_page_alloc(void) |
27 | { | 28 | { |
28 | struct nfs_page *p; | 29 | struct nfs_page *p; |
29 | p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL); | 30 | p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL); |
30 | if (p) { | 31 | if (p) { |
31 | memset(p, 0, sizeof(*p)); | 32 | memset(p, 0, sizeof(*p)); |
32 | INIT_LIST_HEAD(&p->wb_list); | 33 | INIT_LIST_HEAD(&p->wb_list); |
@@ -268,11 +269,10 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, | |||
268 | 269 | ||
269 | #define NFS_SCAN_MAXENTRIES 16 | 270 | #define NFS_SCAN_MAXENTRIES 16 |
270 | /** | 271 | /** |
271 | * nfs_scan_lock_dirty - Scan the radix tree for dirty requests | 272 | * nfs_scan_dirty - Scan the radix tree for dirty requests |
272 | * @nfsi: NFS inode | 273 | * @mapping: pointer to address space |
274 | * @wbc: writeback_control structure | ||
273 | * @dst: Destination list | 275 | * @dst: Destination list |
274 | * @idx_start: lower bound of page->index to scan | ||
275 | * @npages: idx_start + npages sets the upper bound to scan. | ||
276 | * | 276 | * |
277 | * Moves elements from one of the inode request lists. | 277 | * Moves elements from one of the inode request lists. |
278 | * If the number of requests is set to 0, the entire address_space | 278 | * If the number of requests is set to 0, the entire address_space |
@@ -280,46 +280,63 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, | |||
280 | * The requests are *not* checked to ensure that they form a contiguous set. | 280 | * The requests are *not* checked to ensure that they form a contiguous set. |
281 | * You must be holding the inode's req_lock when calling this function | 281 | * You must be holding the inode's req_lock when calling this function |
282 | */ | 282 | */ |
283 | int | 283 | long nfs_scan_dirty(struct address_space *mapping, |
284 | nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst, | 284 | struct writeback_control *wbc, |
285 | unsigned long idx_start, unsigned int npages) | 285 | struct list_head *dst) |
286 | { | 286 | { |
287 | struct nfs_inode *nfsi = NFS_I(mapping->host); | ||
287 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; | 288 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; |
288 | struct nfs_page *req; | 289 | struct nfs_page *req; |
289 | unsigned long idx_end; | 290 | pgoff_t idx_start, idx_end; |
291 | long res = 0; | ||
290 | int found, i; | 292 | int found, i; |
291 | int res; | ||
292 | 293 | ||
293 | res = 0; | 294 | if (nfsi->ndirty == 0) |
294 | if (npages == 0) | 295 | return 0; |
295 | idx_end = ~0; | 296 | if (wbc->range_cyclic) { |
296 | else | 297 | idx_start = 0; |
297 | idx_end = idx_start + npages - 1; | 298 | idx_end = ULONG_MAX; |
299 | } else if (wbc->range_end == 0) { | ||
300 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
301 | idx_end = ULONG_MAX; | ||
302 | } else { | ||
303 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
304 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
305 | } | ||
298 | 306 | ||
299 | for (;;) { | 307 | for (;;) { |
308 | unsigned int toscan = NFS_SCAN_MAXENTRIES; | ||
309 | |||
300 | found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, | 310 | found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, |
301 | (void **)&pgvec[0], idx_start, NFS_SCAN_MAXENTRIES, | 311 | (void **)&pgvec[0], idx_start, toscan, |
302 | NFS_PAGE_TAG_DIRTY); | 312 | NFS_PAGE_TAG_DIRTY); |
313 | |||
314 | /* Did we make progress? */ | ||
303 | if (found <= 0) | 315 | if (found <= 0) |
304 | break; | 316 | break; |
317 | |||
305 | for (i = 0; i < found; i++) { | 318 | for (i = 0; i < found; i++) { |
306 | req = pgvec[i]; | 319 | req = pgvec[i]; |
307 | if (req->wb_index > idx_end) | 320 | if (!wbc->range_cyclic && req->wb_index > idx_end) |
308 | goto out; | 321 | goto out; |
309 | 322 | ||
323 | /* Try to lock request and mark it for writeback */ | ||
324 | if (!nfs_set_page_writeback_locked(req)) | ||
325 | goto next; | ||
326 | radix_tree_tag_clear(&nfsi->nfs_page_tree, | ||
327 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
328 | nfsi->ndirty--; | ||
329 | nfs_list_remove_request(req); | ||
330 | nfs_list_add_request(req, dst); | ||
331 | res++; | ||
332 | if (res == LONG_MAX) | ||
333 | goto out; | ||
334 | next: | ||
310 | idx_start = req->wb_index + 1; | 335 | idx_start = req->wb_index + 1; |
311 | |||
312 | if (nfs_set_page_writeback_locked(req)) { | ||
313 | radix_tree_tag_clear(&nfsi->nfs_page_tree, | ||
314 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
315 | nfs_list_remove_request(req); | ||
316 | nfs_list_add_request(req, dst); | ||
317 | dec_zone_page_state(req->wb_page, NR_FILE_DIRTY); | ||
318 | res++; | ||
319 | } | ||
320 | } | 336 | } |
321 | } | 337 | } |
322 | out: | 338 | out: |
339 | WARN_ON ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)); | ||
323 | return res; | 340 | return res; |
324 | } | 341 | } |
325 | 342 | ||
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 4529cc4f3f8f..560536ad74a4 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -215,32 +215,6 @@ static int nfs_proc_read(struct nfs_read_data *rdata) | |||
215 | return status; | 215 | return status; |
216 | } | 216 | } |
217 | 217 | ||
218 | static int nfs_proc_write(struct nfs_write_data *wdata) | ||
219 | { | ||
220 | int flags = wdata->flags; | ||
221 | struct inode * inode = wdata->inode; | ||
222 | struct nfs_fattr * fattr = wdata->res.fattr; | ||
223 | struct rpc_message msg = { | ||
224 | .rpc_proc = &nfs_procedures[NFSPROC_WRITE], | ||
225 | .rpc_argp = &wdata->args, | ||
226 | .rpc_resp = &wdata->res, | ||
227 | .rpc_cred = wdata->cred, | ||
228 | }; | ||
229 | int status; | ||
230 | |||
231 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
232 | (long long) wdata->args.offset); | ||
233 | nfs_fattr_init(fattr); | ||
234 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); | ||
235 | if (status >= 0) { | ||
236 | nfs_post_op_update_inode(inode, fattr); | ||
237 | wdata->res.count = wdata->args.count; | ||
238 | wdata->verf.committed = NFS_FILE_SYNC; | ||
239 | } | ||
240 | dprintk("NFS reply write: %d\n", status); | ||
241 | return status < 0? status : wdata->res.count; | ||
242 | } | ||
243 | |||
244 | static int | 218 | static int |
245 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 219 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
246 | int flags, struct nameidata *nd) | 220 | int flags, struct nameidata *nd) |
@@ -545,13 +519,10 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
545 | }; | 519 | }; |
546 | int status; | 520 | int status; |
547 | 521 | ||
548 | lock_kernel(); | ||
549 | |||
550 | dprintk("NFS call readdir %d\n", (unsigned int)cookie); | 522 | dprintk("NFS call readdir %d\n", (unsigned int)cookie); |
551 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 523 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
552 | 524 | ||
553 | dprintk("NFS reply readdir: %d\n", status); | 525 | dprintk("NFS reply readdir: %d\n", status); |
554 | unlock_kernel(); | ||
555 | return status; | 526 | return status; |
556 | } | 527 | } |
557 | 528 | ||
@@ -680,7 +651,7 @@ nfs_proc_commit_setup(struct nfs_write_data *data, int how) | |||
680 | static int | 651 | static int |
681 | nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) | 652 | nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) |
682 | { | 653 | { |
683 | return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); | 654 | return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); |
684 | } | 655 | } |
685 | 656 | ||
686 | 657 | ||
@@ -696,8 +667,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = { | |||
696 | .access = NULL, /* access */ | 667 | .access = NULL, /* access */ |
697 | .readlink = nfs_proc_readlink, | 668 | .readlink = nfs_proc_readlink, |
698 | .read = nfs_proc_read, | 669 | .read = nfs_proc_read, |
699 | .write = nfs_proc_write, | ||
700 | .commit = NULL, /* commit */ | ||
701 | .create = nfs_proc_create, | 670 | .create = nfs_proc_create, |
702 | .remove = nfs_proc_remove, | 671 | .remove = nfs_proc_remove, |
703 | .unlink_setup = nfs_proc_unlink_setup, | 672 | .unlink_setup = nfs_proc_unlink_setup, |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index c2e49c397a27..a9c26521a9e2 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <asm/system.h> | 31 | #include <asm/system.h> |
32 | 32 | ||
33 | #include "internal.h" | ||
33 | #include "iostat.h" | 34 | #include "iostat.h" |
34 | 35 | ||
35 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 36 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
@@ -38,7 +39,7 @@ static int nfs_pagein_one(struct list_head *, struct inode *); | |||
38 | static const struct rpc_call_ops nfs_read_partial_ops; | 39 | static const struct rpc_call_ops nfs_read_partial_ops; |
39 | static const struct rpc_call_ops nfs_read_full_ops; | 40 | static const struct rpc_call_ops nfs_read_full_ops; |
40 | 41 | ||
41 | static kmem_cache_t *nfs_rdata_cachep; | 42 | static struct kmem_cache *nfs_rdata_cachep; |
42 | static mempool_t *nfs_rdata_mempool; | 43 | static mempool_t *nfs_rdata_mempool; |
43 | 44 | ||
44 | #define MIN_POOL_READ (32) | 45 | #define MIN_POOL_READ (32) |
@@ -46,7 +47,7 @@ static mempool_t *nfs_rdata_mempool; | |||
46 | struct nfs_read_data *nfs_readdata_alloc(size_t len) | 47 | struct nfs_read_data *nfs_readdata_alloc(size_t len) |
47 | { | 48 | { |
48 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 49 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
49 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); | 50 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS); |
50 | 51 | ||
51 | if (p) { | 52 | if (p) { |
52 | memset(p, 0, sizeof(*p)); | 53 | memset(p, 0, sizeof(*p)); |
@@ -65,32 +66,22 @@ struct nfs_read_data *nfs_readdata_alloc(size_t len) | |||
65 | return p; | 66 | return p; |
66 | } | 67 | } |
67 | 68 | ||
68 | static void nfs_readdata_free(struct nfs_read_data *p) | 69 | static void nfs_readdata_rcu_free(struct rcu_head *head) |
69 | { | 70 | { |
71 | struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu); | ||
70 | if (p && (p->pagevec != &p->page_array[0])) | 72 | if (p && (p->pagevec != &p->page_array[0])) |
71 | kfree(p->pagevec); | 73 | kfree(p->pagevec); |
72 | mempool_free(p, nfs_rdata_mempool); | 74 | mempool_free(p, nfs_rdata_mempool); |
73 | } | 75 | } |
74 | 76 | ||
75 | void nfs_readdata_release(void *data) | 77 | static void nfs_readdata_free(struct nfs_read_data *rdata) |
76 | { | 78 | { |
77 | nfs_readdata_free(data); | 79 | call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free); |
78 | } | 80 | } |
79 | 81 | ||
80 | static | 82 | void nfs_readdata_release(void *data) |
81 | unsigned int nfs_page_length(struct inode *inode, struct page *page) | ||
82 | { | 83 | { |
83 | loff_t i_size = i_size_read(inode); | 84 | nfs_readdata_free(data); |
84 | unsigned long idx; | ||
85 | |||
86 | if (i_size <= 0) | ||
87 | return 0; | ||
88 | idx = (i_size - 1) >> PAGE_CACHE_SHIFT; | ||
89 | if (page->index > idx) | ||
90 | return 0; | ||
91 | if (page->index != idx) | ||
92 | return PAGE_CACHE_SIZE; | ||
93 | return 1 + ((i_size - 1) & (PAGE_CACHE_SIZE - 1)); | ||
94 | } | 85 | } |
95 | 86 | ||
96 | static | 87 | static |
@@ -139,12 +130,12 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
139 | { | 130 | { |
140 | unsigned int rsize = NFS_SERVER(inode)->rsize; | 131 | unsigned int rsize = NFS_SERVER(inode)->rsize; |
141 | unsigned int count = PAGE_CACHE_SIZE; | 132 | unsigned int count = PAGE_CACHE_SIZE; |
142 | int result; | 133 | int result = -ENOMEM; |
143 | struct nfs_read_data *rdata; | 134 | struct nfs_read_data *rdata; |
144 | 135 | ||
145 | rdata = nfs_readdata_alloc(count); | 136 | rdata = nfs_readdata_alloc(count); |
146 | if (!rdata) | 137 | if (!rdata) |
147 | return -ENOMEM; | 138 | goto out_unlock; |
148 | 139 | ||
149 | memset(rdata, 0, sizeof(*rdata)); | 140 | memset(rdata, 0, sizeof(*rdata)); |
150 | rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); | 141 | rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); |
@@ -212,8 +203,9 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
212 | result = 0; | 203 | result = 0; |
213 | 204 | ||
214 | io_error: | 205 | io_error: |
215 | unlock_page(page); | ||
216 | nfs_readdata_free(rdata); | 206 | nfs_readdata_free(rdata); |
207 | out_unlock: | ||
208 | unlock_page(page); | ||
217 | return result; | 209 | return result; |
218 | } | 210 | } |
219 | 211 | ||
@@ -224,7 +216,7 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
224 | struct nfs_page *new; | 216 | struct nfs_page *new; |
225 | unsigned int len; | 217 | unsigned int len; |
226 | 218 | ||
227 | len = nfs_page_length(inode, page); | 219 | len = nfs_page_length(page); |
228 | if (len == 0) | 220 | if (len == 0) |
229 | return nfs_return_empty_page(page); | 221 | return nfs_return_empty_page(page); |
230 | new = nfs_create_request(ctx, inode, page, 0, len); | 222 | new = nfs_create_request(ctx, inode, page, 0, len); |
@@ -316,9 +308,7 @@ static void nfs_execute_read(struct nfs_read_data *data) | |||
316 | sigset_t oldset; | 308 | sigset_t oldset; |
317 | 309 | ||
318 | rpc_clnt_sigmask(clnt, &oldset); | 310 | rpc_clnt_sigmask(clnt, &oldset); |
319 | lock_kernel(); | ||
320 | rpc_execute(&data->task); | 311 | rpc_execute(&data->task); |
321 | unlock_kernel(); | ||
322 | rpc_clnt_sigunmask(clnt, &oldset); | 312 | rpc_clnt_sigunmask(clnt, &oldset); |
323 | } | 313 | } |
324 | 314 | ||
@@ -455,6 +445,55 @@ nfs_pagein_list(struct list_head *head, int rpages) | |||
455 | } | 445 | } |
456 | 446 | ||
457 | /* | 447 | /* |
448 | * This is the callback from RPC telling us whether a reply was | ||
449 | * received or some error occurred (timeout or socket shutdown). | ||
450 | */ | ||
451 | int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) | ||
452 | { | ||
453 | int status; | ||
454 | |||
455 | dprintk("%s: %4d, (status %d)\n", __FUNCTION__, task->tk_pid, | ||
456 | task->tk_status); | ||
457 | |||
458 | status = NFS_PROTO(data->inode)->read_done(task, data); | ||
459 | if (status != 0) | ||
460 | return status; | ||
461 | |||
462 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, data->res.count); | ||
463 | |||
464 | if (task->tk_status == -ESTALE) { | ||
465 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
466 | nfs_mark_for_revalidate(data->inode); | ||
467 | } | ||
468 | spin_lock(&data->inode->i_lock); | ||
469 | NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
470 | spin_unlock(&data->inode->i_lock); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data) | ||
475 | { | ||
476 | struct nfs_readargs *argp = &data->args; | ||
477 | struct nfs_readres *resp = &data->res; | ||
478 | |||
479 | if (resp->eof || resp->count == argp->count) | ||
480 | return 0; | ||
481 | |||
482 | /* This is a short read! */ | ||
483 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | ||
484 | /* Has the server at least made some progress? */ | ||
485 | if (resp->count == 0) | ||
486 | return 0; | ||
487 | |||
488 | /* Yes, so retry the read at the end of the data */ | ||
489 | argp->offset += resp->count; | ||
490 | argp->pgbase += resp->count; | ||
491 | argp->count -= resp->count; | ||
492 | rpc_restart_call(task); | ||
493 | return -EAGAIN; | ||
494 | } | ||
495 | |||
496 | /* | ||
458 | * Handle a read reply that fills part of a page. | 497 | * Handle a read reply that fills part of a page. |
459 | */ | 498 | */ |
460 | static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) | 499 | static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) |
@@ -463,12 +502,16 @@ static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) | |||
463 | struct nfs_page *req = data->req; | 502 | struct nfs_page *req = data->req; |
464 | struct page *page = req->wb_page; | 503 | struct page *page = req->wb_page; |
465 | 504 | ||
466 | if (likely(task->tk_status >= 0)) | ||
467 | nfs_readpage_truncate_uninitialised_page(data); | ||
468 | else | ||
469 | SetPageError(page); | ||
470 | if (nfs_readpage_result(task, data) != 0) | 505 | if (nfs_readpage_result(task, data) != 0) |
471 | return; | 506 | return; |
507 | |||
508 | if (likely(task->tk_status >= 0)) { | ||
509 | nfs_readpage_truncate_uninitialised_page(data); | ||
510 | if (nfs_readpage_retry(task, data) != 0) | ||
511 | return; | ||
512 | } | ||
513 | if (unlikely(task->tk_status < 0)) | ||
514 | SetPageError(page); | ||
472 | if (atomic_dec_and_test(&req->wb_complete)) { | 515 | if (atomic_dec_and_test(&req->wb_complete)) { |
473 | if (!PageError(page)) | 516 | if (!PageError(page)) |
474 | SetPageUptodate(page); | 517 | SetPageUptodate(page); |
@@ -496,25 +539,13 @@ static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data) | |||
496 | count += base; | 539 | count += base; |
497 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) | 540 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) |
498 | SetPageUptodate(*pages); | 541 | SetPageUptodate(*pages); |
499 | if (count != 0) | 542 | if (count == 0) |
543 | return; | ||
544 | /* Was this a short read? */ | ||
545 | if (data->res.eof || data->res.count == data->args.count) | ||
500 | SetPageUptodate(*pages); | 546 | SetPageUptodate(*pages); |
501 | } | 547 | } |
502 | 548 | ||
503 | static void nfs_readpage_set_pages_error(struct nfs_read_data *data) | ||
504 | { | ||
505 | unsigned int count = data->args.count; | ||
506 | unsigned int base = data->args.pgbase; | ||
507 | struct page **pages; | ||
508 | |||
509 | pages = &data->args.pages[base >> PAGE_CACHE_SHIFT]; | ||
510 | base &= ~PAGE_CACHE_MASK; | ||
511 | count += base; | ||
512 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) | ||
513 | SetPageError(*pages); | ||
514 | if (count != 0) | ||
515 | SetPageError(*pages); | ||
516 | } | ||
517 | |||
518 | /* | 549 | /* |
519 | * This is the callback from RPC telling us whether a reply was | 550 | * This is the callback from RPC telling us whether a reply was |
520 | * received or some error occurred (timeout or socket shutdown). | 551 | * received or some error occurred (timeout or socket shutdown). |
@@ -523,19 +554,20 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata) | |||
523 | { | 554 | { |
524 | struct nfs_read_data *data = calldata; | 555 | struct nfs_read_data *data = calldata; |
525 | 556 | ||
557 | if (nfs_readpage_result(task, data) != 0) | ||
558 | return; | ||
526 | /* | 559 | /* |
527 | * Note: nfs_readpage_result may change the values of | 560 | * Note: nfs_readpage_retry may change the values of |
528 | * data->args. In the multi-page case, we therefore need | 561 | * data->args. In the multi-page case, we therefore need |
529 | * to ensure that we call the next nfs_readpage_set_page_uptodate() | 562 | * to ensure that we call nfs_readpage_set_pages_uptodate() |
530 | * first in the multi-page case. | 563 | * first. |
531 | */ | 564 | */ |
532 | if (likely(task->tk_status >= 0)) { | 565 | if (likely(task->tk_status >= 0)) { |
533 | nfs_readpage_truncate_uninitialised_page(data); | 566 | nfs_readpage_truncate_uninitialised_page(data); |
534 | nfs_readpage_set_pages_uptodate(data); | 567 | nfs_readpage_set_pages_uptodate(data); |
535 | } else | 568 | if (nfs_readpage_retry(task, data) != 0) |
536 | nfs_readpage_set_pages_error(data); | 569 | return; |
537 | if (nfs_readpage_result(task, data) != 0) | 570 | } |
538 | return; | ||
539 | while (!list_empty(&data->pages)) { | 571 | while (!list_empty(&data->pages)) { |
540 | struct nfs_page *req = nfs_list_entry(data->pages.next); | 572 | struct nfs_page *req = nfs_list_entry(data->pages.next); |
541 | 573 | ||
@@ -550,50 +582,6 @@ static const struct rpc_call_ops nfs_read_full_ops = { | |||
550 | }; | 582 | }; |
551 | 583 | ||
552 | /* | 584 | /* |
553 | * This is the callback from RPC telling us whether a reply was | ||
554 | * received or some error occurred (timeout or socket shutdown). | ||
555 | */ | ||
556 | int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) | ||
557 | { | ||
558 | struct nfs_readargs *argp = &data->args; | ||
559 | struct nfs_readres *resp = &data->res; | ||
560 | int status; | ||
561 | |||
562 | dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", | ||
563 | task->tk_pid, task->tk_status); | ||
564 | |||
565 | status = NFS_PROTO(data->inode)->read_done(task, data); | ||
566 | if (status != 0) | ||
567 | return status; | ||
568 | |||
569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); | ||
570 | |||
571 | if (task->tk_status < 0) { | ||
572 | if (task->tk_status == -ESTALE) { | ||
573 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
574 | nfs_mark_for_revalidate(data->inode); | ||
575 | } | ||
576 | } else if (resp->count < argp->count && !resp->eof) { | ||
577 | /* This is a short read! */ | ||
578 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | ||
579 | /* Has the server at least made some progress? */ | ||
580 | if (resp->count != 0) { | ||
581 | /* Yes, so retry the read at the end of the data */ | ||
582 | argp->offset += resp->count; | ||
583 | argp->pgbase += resp->count; | ||
584 | argp->count -= resp->count; | ||
585 | rpc_restart_call(task); | ||
586 | return -EAGAIN; | ||
587 | } | ||
588 | task->tk_status = -EIO; | ||
589 | } | ||
590 | spin_lock(&data->inode->i_lock); | ||
591 | NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
592 | spin_unlock(&data->inode->i_lock); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Read a page over NFS. | 585 | * Read a page over NFS. |
598 | * We read the page synchronously in the following case: | 586 | * We read the page synchronously in the following case: |
599 | * - The error flag is set for this page. This happens only when a | 587 | * - The error flag is set for this page. This happens only when a |
@@ -626,9 +614,10 @@ int nfs_readpage(struct file *file, struct page *page) | |||
626 | goto out_error; | 614 | goto out_error; |
627 | 615 | ||
628 | if (file == NULL) { | 616 | if (file == NULL) { |
617 | error = -EBADF; | ||
629 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 618 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
630 | if (ctx == NULL) | 619 | if (ctx == NULL) |
631 | return -EBADF; | 620 | goto out_error; |
632 | } else | 621 | } else |
633 | ctx = get_nfs_open_context((struct nfs_open_context *) | 622 | ctx = get_nfs_open_context((struct nfs_open_context *) |
634 | file->private_data); | 623 | file->private_data); |
@@ -663,7 +652,7 @@ readpage_async_filler(void *data, struct page *page) | |||
663 | unsigned int len; | 652 | unsigned int len; |
664 | 653 | ||
665 | nfs_wb_page(inode, page); | 654 | nfs_wb_page(inode, page); |
666 | len = nfs_page_length(inode, page); | 655 | len = nfs_page_length(page); |
667 | if (len == 0) | 656 | if (len == 0) |
668 | return nfs_return_empty_page(page); | 657 | return nfs_return_empty_page(page); |
669 | new = nfs_create_request(desc->ctx, inode, page, 0, len); | 658 | new = nfs_create_request(desc->ctx, inode, page, 0, len); |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 600bbe630abd..6c686112cc03 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -33,9 +33,7 @@ static int nfs_symlink_filler(struct inode *inode, struct page *page) | |||
33 | { | 33 | { |
34 | int error; | 34 | int error; |
35 | 35 | ||
36 | lock_kernel(); | ||
37 | error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE); | 36 | error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE); |
38 | unlock_kernel(); | ||
39 | if (error < 0) | 37 | if (error < 0) |
40 | goto error; | 38 | goto error; |
41 | SetPageUptodate(page); | 39 | SetPageUptodate(page); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 883dd4a1c157..345492e78643 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/smp_lock.h> | 63 | #include <linux/smp_lock.h> |
64 | 64 | ||
65 | #include "delegation.h" | 65 | #include "delegation.h" |
66 | #include "internal.h" | ||
66 | #include "iostat.h" | 67 | #include "iostat.h" |
67 | 68 | ||
68 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 69 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
@@ -74,18 +75,17 @@ | |||
74 | * Local function declarations | 75 | * Local function declarations |
75 | */ | 76 | */ |
76 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, | 77 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, |
77 | struct inode *, | ||
78 | struct page *, | 78 | struct page *, |
79 | unsigned int, unsigned int); | 79 | unsigned int, unsigned int); |
80 | static void nfs_mark_request_dirty(struct nfs_page *req); | ||
80 | static int nfs_wait_on_write_congestion(struct address_space *, int); | 81 | static int nfs_wait_on_write_congestion(struct address_space *, int); |
81 | static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); | 82 | static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); |
82 | static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, | 83 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); |
83 | unsigned int npages, int how); | ||
84 | static const struct rpc_call_ops nfs_write_partial_ops; | 84 | static const struct rpc_call_ops nfs_write_partial_ops; |
85 | static const struct rpc_call_ops nfs_write_full_ops; | 85 | static const struct rpc_call_ops nfs_write_full_ops; |
86 | static const struct rpc_call_ops nfs_commit_ops; | 86 | static const struct rpc_call_ops nfs_commit_ops; |
87 | 87 | ||
88 | static kmem_cache_t *nfs_wdata_cachep; | 88 | static struct kmem_cache *nfs_wdata_cachep; |
89 | static mempool_t *nfs_wdata_mempool; | 89 | static mempool_t *nfs_wdata_mempool; |
90 | static mempool_t *nfs_commit_mempool; | 90 | static mempool_t *nfs_commit_mempool; |
91 | 91 | ||
@@ -93,7 +93,7 @@ static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); | |||
93 | 93 | ||
94 | struct nfs_write_data *nfs_commit_alloc(void) | 94 | struct nfs_write_data *nfs_commit_alloc(void) |
95 | { | 95 | { |
96 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS); | 96 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); |
97 | 97 | ||
98 | if (p) { | 98 | if (p) { |
99 | memset(p, 0, sizeof(*p)); | 99 | memset(p, 0, sizeof(*p)); |
@@ -102,17 +102,23 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
102 | return p; | 102 | return p; |
103 | } | 103 | } |
104 | 104 | ||
105 | void nfs_commit_free(struct nfs_write_data *p) | 105 | void nfs_commit_rcu_free(struct rcu_head *head) |
106 | { | 106 | { |
107 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
107 | if (p && (p->pagevec != &p->page_array[0])) | 108 | if (p && (p->pagevec != &p->page_array[0])) |
108 | kfree(p->pagevec); | 109 | kfree(p->pagevec); |
109 | mempool_free(p, nfs_commit_mempool); | 110 | mempool_free(p, nfs_commit_mempool); |
110 | } | 111 | } |
111 | 112 | ||
113 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
114 | { | ||
115 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
116 | } | ||
117 | |||
112 | struct nfs_write_data *nfs_writedata_alloc(size_t len) | 118 | struct nfs_write_data *nfs_writedata_alloc(size_t len) |
113 | { | 119 | { |
114 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 120 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
115 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); | 121 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
116 | 122 | ||
117 | if (p) { | 123 | if (p) { |
118 | memset(p, 0, sizeof(*p)); | 124 | memset(p, 0, sizeof(*p)); |
@@ -131,18 +137,47 @@ struct nfs_write_data *nfs_writedata_alloc(size_t len) | |||
131 | return p; | 137 | return p; |
132 | } | 138 | } |
133 | 139 | ||
134 | static void nfs_writedata_free(struct nfs_write_data *p) | 140 | static void nfs_writedata_rcu_free(struct rcu_head *head) |
135 | { | 141 | { |
142 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
136 | if (p && (p->pagevec != &p->page_array[0])) | 143 | if (p && (p->pagevec != &p->page_array[0])) |
137 | kfree(p->pagevec); | 144 | kfree(p->pagevec); |
138 | mempool_free(p, nfs_wdata_mempool); | 145 | mempool_free(p, nfs_wdata_mempool); |
139 | } | 146 | } |
140 | 147 | ||
148 | static void nfs_writedata_free(struct nfs_write_data *wdata) | ||
149 | { | ||
150 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | ||
151 | } | ||
152 | |||
141 | void nfs_writedata_release(void *wdata) | 153 | void nfs_writedata_release(void *wdata) |
142 | { | 154 | { |
143 | nfs_writedata_free(wdata); | 155 | nfs_writedata_free(wdata); |
144 | } | 156 | } |
145 | 157 | ||
158 | static struct nfs_page *nfs_page_find_request_locked(struct page *page) | ||
159 | { | ||
160 | struct nfs_page *req = NULL; | ||
161 | |||
162 | if (PagePrivate(page)) { | ||
163 | req = (struct nfs_page *)page_private(page); | ||
164 | if (req != NULL) | ||
165 | atomic_inc(&req->wb_count); | ||
166 | } | ||
167 | return req; | ||
168 | } | ||
169 | |||
170 | static struct nfs_page *nfs_page_find_request(struct page *page) | ||
171 | { | ||
172 | struct nfs_page *req = NULL; | ||
173 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
174 | |||
175 | spin_lock(req_lock); | ||
176 | req = nfs_page_find_request_locked(page); | ||
177 | spin_unlock(req_lock); | ||
178 | return req; | ||
179 | } | ||
180 | |||
146 | /* Adjust the file length if we're writing beyond the end */ | 181 | /* Adjust the file length if we're writing beyond the end */ |
147 | static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) | 182 | static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) |
148 | { | 183 | { |
@@ -164,113 +199,34 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c | |||
164 | */ | 199 | */ |
165 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) | 200 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) |
166 | { | 201 | { |
167 | loff_t end_offs; | ||
168 | |||
169 | if (PageUptodate(page)) | 202 | if (PageUptodate(page)) |
170 | return; | 203 | return; |
171 | if (base != 0) | 204 | if (base != 0) |
172 | return; | 205 | return; |
173 | if (count == PAGE_CACHE_SIZE) { | 206 | if (count != nfs_page_length(page)) |
174 | SetPageUptodate(page); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | end_offs = i_size_read(page->mapping->host) - 1; | ||
179 | if (end_offs < 0) | ||
180 | return; | 207 | return; |
181 | /* Is this the last page? */ | 208 | if (count != PAGE_CACHE_SIZE) |
182 | if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT)) | ||
183 | return; | ||
184 | /* This is the last page: set PG_uptodate if we cover the entire | ||
185 | * extent of the data, then zero the rest of the page. | ||
186 | */ | ||
187 | if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) { | ||
188 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); | 209 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); |
189 | SetPageUptodate(page); | 210 | SetPageUptodate(page); |
190 | } | ||
191 | } | 211 | } |
192 | 212 | ||
193 | /* | 213 | static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, |
194 | * Write a page synchronously. | ||
195 | * Offset is the data offset within the page. | ||
196 | */ | ||
197 | static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | ||
198 | struct page *page, unsigned int offset, unsigned int count, | ||
199 | int how) | ||
200 | { | ||
201 | unsigned int wsize = NFS_SERVER(inode)->wsize; | ||
202 | int result, written = 0; | ||
203 | struct nfs_write_data *wdata; | ||
204 | |||
205 | wdata = nfs_writedata_alloc(wsize); | ||
206 | if (!wdata) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | wdata->flags = how; | ||
210 | wdata->cred = ctx->cred; | ||
211 | wdata->inode = inode; | ||
212 | wdata->args.fh = NFS_FH(inode); | ||
213 | wdata->args.context = ctx; | ||
214 | wdata->args.pages = &page; | ||
215 | wdata->args.stable = NFS_FILE_SYNC; | ||
216 | wdata->args.pgbase = offset; | ||
217 | wdata->args.count = wsize; | ||
218 | wdata->res.fattr = &wdata->fattr; | ||
219 | wdata->res.verf = &wdata->verf; | ||
220 | |||
221 | dprintk("NFS: nfs_writepage_sync(%s/%Ld %d@%Ld)\n", | ||
222 | inode->i_sb->s_id, | ||
223 | (long long)NFS_FILEID(inode), | ||
224 | count, (long long)(page_offset(page) + offset)); | ||
225 | |||
226 | set_page_writeback(page); | ||
227 | nfs_begin_data_update(inode); | ||
228 | do { | ||
229 | if (count < wsize) | ||
230 | wdata->args.count = count; | ||
231 | wdata->args.offset = page_offset(page) + wdata->args.pgbase; | ||
232 | |||
233 | result = NFS_PROTO(inode)->write(wdata); | ||
234 | |||
235 | if (result < 0) { | ||
236 | /* Must mark the page invalid after I/O error */ | ||
237 | ClearPageUptodate(page); | ||
238 | goto io_error; | ||
239 | } | ||
240 | if (result < wdata->args.count) | ||
241 | printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n", | ||
242 | wdata->args.count, result); | ||
243 | |||
244 | wdata->args.offset += result; | ||
245 | wdata->args.pgbase += result; | ||
246 | written += result; | ||
247 | count -= result; | ||
248 | nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result); | ||
249 | } while (count); | ||
250 | /* Update file length */ | ||
251 | nfs_grow_file(page, offset, written); | ||
252 | /* Set the PG_uptodate flag? */ | ||
253 | nfs_mark_uptodate(page, offset, written); | ||
254 | |||
255 | if (PageError(page)) | ||
256 | ClearPageError(page); | ||
257 | |||
258 | io_error: | ||
259 | nfs_end_data_update(inode); | ||
260 | end_page_writeback(page); | ||
261 | nfs_writedata_free(wdata); | ||
262 | return written ? written : result; | ||
263 | } | ||
264 | |||
265 | static int nfs_writepage_async(struct nfs_open_context *ctx, | ||
266 | struct inode *inode, struct page *page, | ||
267 | unsigned int offset, unsigned int count) | 214 | unsigned int offset, unsigned int count) |
268 | { | 215 | { |
269 | struct nfs_page *req; | 216 | struct nfs_page *req; |
217 | int ret; | ||
270 | 218 | ||
271 | req = nfs_update_request(ctx, inode, page, offset, count); | 219 | for (;;) { |
272 | if (IS_ERR(req)) | 220 | req = nfs_update_request(ctx, page, offset, count); |
273 | return PTR_ERR(req); | 221 | if (!IS_ERR(req)) |
222 | break; | ||
223 | ret = PTR_ERR(req); | ||
224 | if (ret != -EBUSY) | ||
225 | return ret; | ||
226 | ret = nfs_wb_page(page->mapping->host, page); | ||
227 | if (ret != 0) | ||
228 | return ret; | ||
229 | } | ||
274 | /* Update file length */ | 230 | /* Update file length */ |
275 | nfs_grow_file(page, offset, count); | 231 | nfs_grow_file(page, offset, count); |
276 | /* Set the PG_uptodate flag? */ | 232 | /* Set the PG_uptodate flag? */ |
@@ -289,73 +245,94 @@ static int wb_priority(struct writeback_control *wbc) | |||
289 | } | 245 | } |
290 | 246 | ||
291 | /* | 247 | /* |
248 | * Find an associated nfs write request, and prepare to flush it out | ||
249 | * Returns 1 if there was no write request, or if the request was | ||
250 | * already tagged by nfs_set_page_dirty.Returns 0 if the request | ||
251 | * was not tagged. | ||
252 | * May also return an error if the user signalled nfs_wait_on_request(). | ||
253 | */ | ||
254 | static int nfs_page_mark_flush(struct page *page) | ||
255 | { | ||
256 | struct nfs_page *req; | ||
257 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
258 | int ret; | ||
259 | |||
260 | spin_lock(req_lock); | ||
261 | for(;;) { | ||
262 | req = nfs_page_find_request_locked(page); | ||
263 | if (req == NULL) { | ||
264 | spin_unlock(req_lock); | ||
265 | return 1; | ||
266 | } | ||
267 | if (nfs_lock_request_dontget(req)) | ||
268 | break; | ||
269 | /* Note: If we hold the page lock, as is the case in nfs_writepage, | ||
270 | * then the call to nfs_lock_request_dontget() will always | ||
271 | * succeed provided that someone hasn't already marked the | ||
272 | * request as dirty (in which case we don't care). | ||
273 | */ | ||
274 | spin_unlock(req_lock); | ||
275 | ret = nfs_wait_on_request(req); | ||
276 | nfs_release_request(req); | ||
277 | if (ret != 0) | ||
278 | return ret; | ||
279 | spin_lock(req_lock); | ||
280 | } | ||
281 | spin_unlock(req_lock); | ||
282 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { | ||
283 | nfs_mark_request_dirty(req); | ||
284 | set_page_writeback(page); | ||
285 | } | ||
286 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | ||
287 | nfs_unlock_request(req); | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Write an mmapped page to the server. | 292 | * Write an mmapped page to the server. |
293 | */ | 293 | */ |
294 | int nfs_writepage(struct page *page, struct writeback_control *wbc) | 294 | static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc) |
295 | { | 295 | { |
296 | struct nfs_open_context *ctx; | 296 | struct nfs_open_context *ctx; |
297 | struct inode *inode = page->mapping->host; | 297 | struct inode *inode = page->mapping->host; |
298 | unsigned long end_index; | 298 | unsigned offset; |
299 | unsigned offset = PAGE_CACHE_SIZE; | ||
300 | loff_t i_size = i_size_read(inode); | ||
301 | int inode_referenced = 0; | ||
302 | int priority = wb_priority(wbc); | ||
303 | int err; | 299 | int err; |
304 | 300 | ||
305 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); | 301 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); |
306 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); | 302 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); |
307 | 303 | ||
308 | /* | 304 | err = nfs_page_mark_flush(page); |
309 | * Note: We need to ensure that we have a reference to the inode | 305 | if (err <= 0) |
310 | * if we are to do asynchronous writes. If not, waiting | 306 | goto out; |
311 | * in nfs_wait_on_request() may deadlock with clear_inode(). | 307 | err = 0; |
312 | * | 308 | offset = nfs_page_length(page); |
313 | * If igrab() fails here, then it is in any case safe to | 309 | if (!offset) |
314 | * call nfs_wb_page(), since there will be no pending writes. | ||
315 | */ | ||
316 | if (igrab(inode) != 0) | ||
317 | inode_referenced = 1; | ||
318 | end_index = i_size >> PAGE_CACHE_SHIFT; | ||
319 | |||
320 | /* Ensure we've flushed out any previous writes */ | ||
321 | nfs_wb_page_priority(inode, page, priority); | ||
322 | |||
323 | /* easy case */ | ||
324 | if (page->index < end_index) | ||
325 | goto do_it; | ||
326 | /* things got complicated... */ | ||
327 | offset = i_size & (PAGE_CACHE_SIZE-1); | ||
328 | |||
329 | /* OK, are we completely out? */ | ||
330 | err = 0; /* potential race with truncate - ignore */ | ||
331 | if (page->index >= end_index+1 || !offset) | ||
332 | goto out; | 310 | goto out; |
333 | do_it: | 311 | |
334 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); | 312 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); |
335 | if (ctx == NULL) { | 313 | if (ctx == NULL) { |
336 | err = -EBADF; | 314 | err = -EBADF; |
337 | goto out; | 315 | goto out; |
338 | } | 316 | } |
339 | lock_kernel(); | 317 | err = nfs_writepage_setup(ctx, page, 0, offset); |
340 | if (!IS_SYNC(inode) && inode_referenced) { | ||
341 | err = nfs_writepage_async(ctx, inode, page, 0, offset); | ||
342 | if (!wbc->for_writepages) | ||
343 | nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); | ||
344 | } else { | ||
345 | err = nfs_writepage_sync(ctx, inode, page, 0, | ||
346 | offset, priority); | ||
347 | if (err >= 0) { | ||
348 | if (err != offset) | ||
349 | redirty_page_for_writepage(wbc, page); | ||
350 | err = 0; | ||
351 | } | ||
352 | } | ||
353 | unlock_kernel(); | ||
354 | put_nfs_open_context(ctx); | 318 | put_nfs_open_context(ctx); |
319 | if (err != 0) | ||
320 | goto out; | ||
321 | err = nfs_page_mark_flush(page); | ||
322 | if (err > 0) | ||
323 | err = 0; | ||
355 | out: | 324 | out: |
325 | if (!wbc->for_writepages) | ||
326 | nfs_flush_mapping(page->mapping, wbc, wb_priority(wbc)); | ||
327 | return err; | ||
328 | } | ||
329 | |||
330 | int nfs_writepage(struct page *page, struct writeback_control *wbc) | ||
331 | { | ||
332 | int err; | ||
333 | |||
334 | err = nfs_writepage_locked(page, wbc); | ||
356 | unlock_page(page); | 335 | unlock_page(page); |
357 | if (inode_referenced) | ||
358 | iput(inode); | ||
359 | return err; | 336 | return err; |
360 | } | 337 | } |
361 | 338 | ||
@@ -379,21 +356,18 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
379 | return 0; | 356 | return 0; |
380 | nfs_wait_on_write_congestion(mapping, 0); | 357 | nfs_wait_on_write_congestion(mapping, 0); |
381 | } | 358 | } |
382 | err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); | 359 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); |
383 | if (err < 0) | 360 | if (err < 0) |
384 | goto out; | 361 | goto out; |
385 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | 362 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); |
386 | wbc->nr_to_write -= err; | ||
387 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { | 363 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { |
388 | err = nfs_wait_on_requests(inode, 0, 0); | 364 | err = nfs_wait_on_requests(inode, 0, 0); |
389 | if (err < 0) | 365 | if (err < 0) |
390 | goto out; | 366 | goto out; |
391 | } | 367 | } |
392 | err = nfs_commit_inode(inode, wb_priority(wbc)); | 368 | err = nfs_commit_inode(inode, wb_priority(wbc)); |
393 | if (err > 0) { | 369 | if (err > 0) |
394 | wbc->nr_to_write -= err; | ||
395 | err = 0; | 370 | err = 0; |
396 | } | ||
397 | out: | 371 | out: |
398 | clear_bit(BDI_write_congested, &bdi->state); | 372 | clear_bit(BDI_write_congested, &bdi->state); |
399 | wake_up_all(&nfs_write_congestion); | 373 | wake_up_all(&nfs_write_congestion); |
@@ -420,6 +394,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
420 | nfsi->change_attr++; | 394 | nfsi->change_attr++; |
421 | } | 395 | } |
422 | SetPagePrivate(req->wb_page); | 396 | SetPagePrivate(req->wb_page); |
397 | set_page_private(req->wb_page, (unsigned long)req); | ||
423 | nfsi->npages++; | 398 | nfsi->npages++; |
424 | atomic_inc(&req->wb_count); | 399 | atomic_inc(&req->wb_count); |
425 | return 0; | 400 | return 0; |
@@ -436,6 +411,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
436 | BUG_ON (!NFS_WBACK_BUSY(req)); | 411 | BUG_ON (!NFS_WBACK_BUSY(req)); |
437 | 412 | ||
438 | spin_lock(&nfsi->req_lock); | 413 | spin_lock(&nfsi->req_lock); |
414 | set_page_private(req->wb_page, 0); | ||
439 | ClearPagePrivate(req->wb_page); | 415 | ClearPagePrivate(req->wb_page); |
440 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 416 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
441 | nfsi->npages--; | 417 | nfsi->npages--; |
@@ -450,33 +426,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
450 | } | 426 | } |
451 | 427 | ||
452 | /* | 428 | /* |
453 | * Find a request | ||
454 | */ | ||
455 | static inline struct nfs_page * | ||
456 | _nfs_find_request(struct inode *inode, unsigned long index) | ||
457 | { | ||
458 | struct nfs_inode *nfsi = NFS_I(inode); | ||
459 | struct nfs_page *req; | ||
460 | |||
461 | req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index); | ||
462 | if (req) | ||
463 | atomic_inc(&req->wb_count); | ||
464 | return req; | ||
465 | } | ||
466 | |||
467 | static struct nfs_page * | ||
468 | nfs_find_request(struct inode *inode, unsigned long index) | ||
469 | { | ||
470 | struct nfs_page *req; | ||
471 | struct nfs_inode *nfsi = NFS_I(inode); | ||
472 | |||
473 | spin_lock(&nfsi->req_lock); | ||
474 | req = _nfs_find_request(inode, index); | ||
475 | spin_unlock(&nfsi->req_lock); | ||
476 | return req; | ||
477 | } | ||
478 | |||
479 | /* | ||
480 | * Add a request to the inode's dirty list. | 429 | * Add a request to the inode's dirty list. |
481 | */ | 430 | */ |
482 | static void | 431 | static void |
@@ -491,8 +440,14 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
491 | nfs_list_add_request(req, &nfsi->dirty); | 440 | nfs_list_add_request(req, &nfsi->dirty); |
492 | nfsi->ndirty++; | 441 | nfsi->ndirty++; |
493 | spin_unlock(&nfsi->req_lock); | 442 | spin_unlock(&nfsi->req_lock); |
494 | inc_zone_page_state(req->wb_page, NR_FILE_DIRTY); | 443 | __mark_inode_dirty(inode, I_DIRTY_PAGES); |
495 | mark_inode_dirty(inode); | 444 | } |
445 | |||
446 | static void | ||
447 | nfs_redirty_request(struct nfs_page *req) | ||
448 | { | ||
449 | clear_bit(PG_FLUSHING, &req->wb_flags); | ||
450 | __set_page_dirty_nobuffers(req->wb_page); | ||
496 | } | 451 | } |
497 | 452 | ||
498 | /* | 453 | /* |
@@ -501,8 +456,7 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
501 | static inline int | 456 | static inline int |
502 | nfs_dirty_request(struct nfs_page *req) | 457 | nfs_dirty_request(struct nfs_page *req) |
503 | { | 458 | { |
504 | struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode); | 459 | return test_bit(PG_FLUSHING, &req->wb_flags) == 0; |
505 | return !list_empty(&req->wb_list) && req->wb_list_head == &nfsi->dirty; | ||
506 | } | 460 | } |
507 | 461 | ||
508 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 462 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
@@ -520,7 +474,7 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
520 | nfsi->ncommit++; | 474 | nfsi->ncommit++; |
521 | spin_unlock(&nfsi->req_lock); | 475 | spin_unlock(&nfsi->req_lock); |
522 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 476 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
523 | mark_inode_dirty(inode); | 477 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
524 | } | 478 | } |
525 | #endif | 479 | #endif |
526 | 480 | ||
@@ -597,31 +551,6 @@ static void nfs_cancel_commit_list(struct list_head *head) | |||
597 | } | 551 | } |
598 | } | 552 | } |
599 | 553 | ||
600 | /* | ||
601 | * nfs_scan_dirty - Scan an inode for dirty requests | ||
602 | * @inode: NFS inode to scan | ||
603 | * @dst: destination list | ||
604 | * @idx_start: lower bound of page->index to scan. | ||
605 | * @npages: idx_start + npages sets the upper bound to scan. | ||
606 | * | ||
607 | * Moves requests from the inode's dirty page list. | ||
608 | * The requests are *not* checked to ensure that they form a contiguous set. | ||
609 | */ | ||
610 | static int | ||
611 | nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) | ||
612 | { | ||
613 | struct nfs_inode *nfsi = NFS_I(inode); | ||
614 | int res = 0; | ||
615 | |||
616 | if (nfsi->ndirty != 0) { | ||
617 | res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages); | ||
618 | nfsi->ndirty -= res; | ||
619 | if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) | ||
620 | printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); | ||
621 | } | ||
622 | return res; | ||
623 | } | ||
624 | |||
625 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 554 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
626 | /* | 555 | /* |
627 | * nfs_scan_commit - Scan an inode for commit requests | 556 | * nfs_scan_commit - Scan an inode for commit requests |
@@ -698,27 +627,27 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
698 | * Note: Should always be called with the Page Lock held! | 627 | * Note: Should always be called with the Page Lock held! |
699 | */ | 628 | */ |
700 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | 629 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, |
701 | struct inode *inode, struct page *page, | 630 | struct page *page, unsigned int offset, unsigned int bytes) |
702 | unsigned int offset, unsigned int bytes) | ||
703 | { | 631 | { |
704 | struct nfs_server *server = NFS_SERVER(inode); | 632 | struct inode *inode = page->mapping->host; |
705 | struct nfs_inode *nfsi = NFS_I(inode); | 633 | struct nfs_inode *nfsi = NFS_I(inode); |
706 | struct nfs_page *req, *new = NULL; | 634 | struct nfs_page *req, *new = NULL; |
707 | unsigned long rqend, end; | 635 | unsigned long rqend, end; |
708 | 636 | ||
709 | end = offset + bytes; | 637 | end = offset + bytes; |
710 | 638 | ||
711 | if (nfs_wait_on_write_congestion(page->mapping, server->flags & NFS_MOUNT_INTR)) | 639 | if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) |
712 | return ERR_PTR(-ERESTARTSYS); | 640 | return ERR_PTR(-ERESTARTSYS); |
713 | for (;;) { | 641 | for (;;) { |
714 | /* Loop over all inode entries and see if we find | 642 | /* Loop over all inode entries and see if we find |
715 | * A request for the page we wish to update | 643 | * A request for the page we wish to update |
716 | */ | 644 | */ |
717 | spin_lock(&nfsi->req_lock); | 645 | spin_lock(&nfsi->req_lock); |
718 | req = _nfs_find_request(inode, page->index); | 646 | req = nfs_page_find_request_locked(page); |
719 | if (req) { | 647 | if (req) { |
720 | if (!nfs_lock_request_dontget(req)) { | 648 | if (!nfs_lock_request_dontget(req)) { |
721 | int error; | 649 | int error; |
650 | |||
722 | spin_unlock(&nfsi->req_lock); | 651 | spin_unlock(&nfsi->req_lock); |
723 | error = nfs_wait_on_request(req); | 652 | error = nfs_wait_on_request(req); |
724 | nfs_release_request(req); | 653 | nfs_release_request(req); |
@@ -745,7 +674,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
745 | return ERR_PTR(error); | 674 | return ERR_PTR(error); |
746 | } | 675 | } |
747 | spin_unlock(&nfsi->req_lock); | 676 | spin_unlock(&nfsi->req_lock); |
748 | nfs_mark_request_dirty(new); | ||
749 | return new; | 677 | return new; |
750 | } | 678 | } |
751 | spin_unlock(&nfsi->req_lock); | 679 | spin_unlock(&nfsi->req_lock); |
@@ -786,9 +714,8 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
786 | int nfs_flush_incompatible(struct file *file, struct page *page) | 714 | int nfs_flush_incompatible(struct file *file, struct page *page) |
787 | { | 715 | { |
788 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 716 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
789 | struct inode *inode = page->mapping->host; | ||
790 | struct nfs_page *req; | 717 | struct nfs_page *req; |
791 | int status = 0; | 718 | int do_flush, status; |
792 | /* | 719 | /* |
793 | * Look for a request corresponding to this page. If there | 720 | * Look for a request corresponding to this page. If there |
794 | * is one, and it belongs to another file, we flush it out | 721 | * is one, and it belongs to another file, we flush it out |
@@ -797,13 +724,18 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
797 | * Also do the same if we find a request from an existing | 724 | * Also do the same if we find a request from an existing |
798 | * dropped page. | 725 | * dropped page. |
799 | */ | 726 | */ |
800 | req = nfs_find_request(inode, page->index); | 727 | do { |
801 | if (req) { | 728 | req = nfs_page_find_request(page); |
802 | if (req->wb_page != page || ctx != req->wb_context) | 729 | if (req == NULL) |
803 | status = nfs_wb_page(inode, page); | 730 | return 0; |
731 | do_flush = req->wb_page != page || req->wb_context != ctx | ||
732 | || !nfs_dirty_request(req); | ||
804 | nfs_release_request(req); | 733 | nfs_release_request(req); |
805 | } | 734 | if (!do_flush) |
806 | return (status < 0) ? status : 0; | 735 | return 0; |
736 | status = nfs_wb_page(page->mapping->host, page); | ||
737 | } while (status == 0); | ||
738 | return status; | ||
807 | } | 739 | } |
808 | 740 | ||
809 | /* | 741 | /* |
@@ -817,72 +749,27 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
817 | { | 749 | { |
818 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 750 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
819 | struct inode *inode = page->mapping->host; | 751 | struct inode *inode = page->mapping->host; |
820 | struct nfs_page *req; | ||
821 | int status = 0; | 752 | int status = 0; |
822 | 753 | ||
823 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); | 754 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); |
824 | 755 | ||
825 | dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", | 756 | dprintk("NFS: nfs_updatepage(%s/%s %d@%Ld)\n", |
826 | file->f_dentry->d_parent->d_name.name, | 757 | file->f_path.dentry->d_parent->d_name.name, |
827 | file->f_dentry->d_name.name, count, | 758 | file->f_path.dentry->d_name.name, count, |
828 | (long long)(page_offset(page) +offset)); | 759 | (long long)(page_offset(page) +offset)); |
829 | 760 | ||
830 | if (IS_SYNC(inode)) { | ||
831 | status = nfs_writepage_sync(ctx, inode, page, offset, count, 0); | ||
832 | if (status > 0) { | ||
833 | if (offset == 0 && status == PAGE_CACHE_SIZE) | ||
834 | SetPageUptodate(page); | ||
835 | return 0; | ||
836 | } | ||
837 | return status; | ||
838 | } | ||
839 | |||
840 | /* If we're not using byte range locks, and we know the page | 761 | /* If we're not using byte range locks, and we know the page |
841 | * is entirely in cache, it may be more efficient to avoid | 762 | * is entirely in cache, it may be more efficient to avoid |
842 | * fragmenting write requests. | 763 | * fragmenting write requests. |
843 | */ | 764 | */ |
844 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { | 765 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
845 | loff_t end_offs = i_size_read(inode) - 1; | 766 | count = max(count + offset, nfs_page_length(page)); |
846 | unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; | ||
847 | |||
848 | count += offset; | ||
849 | offset = 0; | 767 | offset = 0; |
850 | if (unlikely(end_offs < 0)) { | ||
851 | /* Do nothing */ | ||
852 | } else if (page->index == end_index) { | ||
853 | unsigned int pglen; | ||
854 | pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1; | ||
855 | if (count < pglen) | ||
856 | count = pglen; | ||
857 | } else if (page->index < end_index) | ||
858 | count = PAGE_CACHE_SIZE; | ||
859 | } | 768 | } |
860 | 769 | ||
861 | /* | 770 | status = nfs_writepage_setup(ctx, page, offset, count); |
862 | * Try to find an NFS request corresponding to this page | 771 | __set_page_dirty_nobuffers(page); |
863 | * and update it. | ||
864 | * If the existing request cannot be updated, we must flush | ||
865 | * it out now. | ||
866 | */ | ||
867 | do { | ||
868 | req = nfs_update_request(ctx, inode, page, offset, count); | ||
869 | status = (IS_ERR(req)) ? PTR_ERR(req) : 0; | ||
870 | if (status != -EBUSY) | ||
871 | break; | ||
872 | /* Request could not be updated. Flush it out and try again */ | ||
873 | status = nfs_wb_page(inode, page); | ||
874 | } while (status >= 0); | ||
875 | if (status < 0) | ||
876 | goto done; | ||
877 | |||
878 | status = 0; | ||
879 | 772 | ||
880 | /* Update file length */ | ||
881 | nfs_grow_file(page, offset, count); | ||
882 | /* Set the PG_uptodate flag? */ | ||
883 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); | ||
884 | nfs_unlock_request(req); | ||
885 | done: | ||
886 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", | 773 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", |
887 | status, (long long)i_size_read(inode)); | 774 | status, (long long)i_size_read(inode)); |
888 | if (status < 0) | 775 | if (status < 0) |
@@ -897,7 +784,7 @@ static void nfs_writepage_release(struct nfs_page *req) | |||
897 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 784 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
898 | if (!PageError(req->wb_page)) { | 785 | if (!PageError(req->wb_page)) { |
899 | if (NFS_NEED_RESCHED(req)) { | 786 | if (NFS_NEED_RESCHED(req)) { |
900 | nfs_mark_request_dirty(req); | 787 | nfs_redirty_request(req); |
901 | goto out; | 788 | goto out; |
902 | } else if (NFS_NEED_COMMIT(req)) { | 789 | } else if (NFS_NEED_COMMIT(req)) { |
903 | nfs_mark_request_commit(req); | 790 | nfs_mark_request_commit(req); |
@@ -979,9 +866,7 @@ static void nfs_execute_write(struct nfs_write_data *data) | |||
979 | sigset_t oldset; | 866 | sigset_t oldset; |
980 | 867 | ||
981 | rpc_clnt_sigmask(clnt, &oldset); | 868 | rpc_clnt_sigmask(clnt, &oldset); |
982 | lock_kernel(); | ||
983 | rpc_execute(&data->task); | 869 | rpc_execute(&data->task); |
984 | unlock_kernel(); | ||
985 | rpc_clnt_sigunmask(clnt, &oldset); | 870 | rpc_clnt_sigunmask(clnt, &oldset); |
986 | } | 871 | } |
987 | 872 | ||
@@ -1015,7 +900,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) | |||
1015 | atomic_set(&req->wb_complete, requests); | 900 | atomic_set(&req->wb_complete, requests); |
1016 | 901 | ||
1017 | ClearPageError(page); | 902 | ClearPageError(page); |
1018 | set_page_writeback(page); | ||
1019 | offset = 0; | 903 | offset = 0; |
1020 | nbytes = req->wb_bytes; | 904 | nbytes = req->wb_bytes; |
1021 | do { | 905 | do { |
@@ -1043,9 +927,9 @@ out_bad: | |||
1043 | while (!list_empty(&list)) { | 927 | while (!list_empty(&list)) { |
1044 | data = list_entry(list.next, struct nfs_write_data, pages); | 928 | data = list_entry(list.next, struct nfs_write_data, pages); |
1045 | list_del(&data->pages); | 929 | list_del(&data->pages); |
1046 | nfs_writedata_free(data); | 930 | nfs_writedata_release(data); |
1047 | } | 931 | } |
1048 | nfs_mark_request_dirty(req); | 932 | nfs_redirty_request(req); |
1049 | nfs_clear_page_writeback(req); | 933 | nfs_clear_page_writeback(req); |
1050 | return -ENOMEM; | 934 | return -ENOMEM; |
1051 | } | 935 | } |
@@ -1076,7 +960,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
1076 | nfs_list_remove_request(req); | 960 | nfs_list_remove_request(req); |
1077 | nfs_list_add_request(req, &data->pages); | 961 | nfs_list_add_request(req, &data->pages); |
1078 | ClearPageError(req->wb_page); | 962 | ClearPageError(req->wb_page); |
1079 | set_page_writeback(req->wb_page); | ||
1080 | *pages++ = req->wb_page; | 963 | *pages++ = req->wb_page; |
1081 | count += req->wb_bytes; | 964 | count += req->wb_bytes; |
1082 | } | 965 | } |
@@ -1091,7 +974,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
1091 | while (!list_empty(head)) { | 974 | while (!list_empty(head)) { |
1092 | struct nfs_page *req = nfs_list_entry(head->next); | 975 | struct nfs_page *req = nfs_list_entry(head->next); |
1093 | nfs_list_remove_request(req); | 976 | nfs_list_remove_request(req); |
1094 | nfs_mark_request_dirty(req); | 977 | nfs_redirty_request(req); |
1095 | nfs_clear_page_writeback(req); | 978 | nfs_clear_page_writeback(req); |
1096 | } | 979 | } |
1097 | return -ENOMEM; | 980 | return -ENOMEM; |
@@ -1126,7 +1009,7 @@ out_err: | |||
1126 | while (!list_empty(head)) { | 1009 | while (!list_empty(head)) { |
1127 | req = nfs_list_entry(head->next); | 1010 | req = nfs_list_entry(head->next); |
1128 | nfs_list_remove_request(req); | 1011 | nfs_list_remove_request(req); |
1129 | nfs_mark_request_dirty(req); | 1012 | nfs_redirty_request(req); |
1130 | nfs_clear_page_writeback(req); | 1013 | nfs_clear_page_writeback(req); |
1131 | } | 1014 | } |
1132 | return error; | 1015 | return error; |
@@ -1442,7 +1325,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) | |||
1442 | } | 1325 | } |
1443 | /* We have a mismatch. Write the page again */ | 1326 | /* We have a mismatch. Write the page again */ |
1444 | dprintk(" mismatch\n"); | 1327 | dprintk(" mismatch\n"); |
1445 | nfs_mark_request_dirty(req); | 1328 | nfs_redirty_request(req); |
1446 | next: | 1329 | next: |
1447 | nfs_clear_page_writeback(req); | 1330 | nfs_clear_page_writeback(req); |
1448 | } | 1331 | } |
@@ -1459,18 +1342,17 @@ static inline int nfs_commit_list(struct inode *inode, struct list_head *head, i | |||
1459 | } | 1342 | } |
1460 | #endif | 1343 | #endif |
1461 | 1344 | ||
1462 | static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, | 1345 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) |
1463 | unsigned int npages, int how) | ||
1464 | { | 1346 | { |
1465 | struct nfs_inode *nfsi = NFS_I(inode); | 1347 | struct nfs_inode *nfsi = NFS_I(mapping->host); |
1466 | LIST_HEAD(head); | 1348 | LIST_HEAD(head); |
1467 | int res; | 1349 | long res; |
1468 | 1350 | ||
1469 | spin_lock(&nfsi->req_lock); | 1351 | spin_lock(&nfsi->req_lock); |
1470 | res = nfs_scan_dirty(inode, &head, idx_start, npages); | 1352 | res = nfs_scan_dirty(mapping, wbc, &head); |
1471 | spin_unlock(&nfsi->req_lock); | 1353 | spin_unlock(&nfsi->req_lock); |
1472 | if (res) { | 1354 | if (res) { |
1473 | int error = nfs_flush_list(inode, &head, res, how); | 1355 | int error = nfs_flush_list(mapping->host, &head, res, how); |
1474 | if (error < 0) | 1356 | if (error < 0) |
1475 | return error; | 1357 | return error; |
1476 | } | 1358 | } |
@@ -1496,38 +1378,62 @@ int nfs_commit_inode(struct inode *inode, int how) | |||
1496 | } | 1378 | } |
1497 | #endif | 1379 | #endif |
1498 | 1380 | ||
1499 | int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, | 1381 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) |
1500 | unsigned int npages, int how) | ||
1501 | { | 1382 | { |
1383 | struct inode *inode = mapping->host; | ||
1502 | struct nfs_inode *nfsi = NFS_I(inode); | 1384 | struct nfs_inode *nfsi = NFS_I(inode); |
1385 | unsigned long idx_start, idx_end; | ||
1386 | unsigned int npages = 0; | ||
1503 | LIST_HEAD(head); | 1387 | LIST_HEAD(head); |
1504 | int nocommit = how & FLUSH_NOCOMMIT; | 1388 | int nocommit = how & FLUSH_NOCOMMIT; |
1505 | int pages, ret; | 1389 | long pages, ret; |
1506 | 1390 | ||
1391 | /* FIXME */ | ||
1392 | if (wbc->range_cyclic) | ||
1393 | idx_start = 0; | ||
1394 | else { | ||
1395 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
1396 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
1397 | if (idx_end > idx_start) { | ||
1398 | unsigned long l_npages = 1 + idx_end - idx_start; | ||
1399 | npages = l_npages; | ||
1400 | if (sizeof(npages) != sizeof(l_npages) && | ||
1401 | (unsigned long)npages != l_npages) | ||
1402 | npages = 0; | ||
1403 | } | ||
1404 | } | ||
1507 | how &= ~FLUSH_NOCOMMIT; | 1405 | how &= ~FLUSH_NOCOMMIT; |
1508 | spin_lock(&nfsi->req_lock); | 1406 | spin_lock(&nfsi->req_lock); |
1509 | do { | 1407 | do { |
1408 | wbc->pages_skipped = 0; | ||
1510 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); | 1409 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); |
1511 | if (ret != 0) | 1410 | if (ret != 0) |
1512 | continue; | 1411 | continue; |
1513 | pages = nfs_scan_dirty(inode, &head, idx_start, npages); | 1412 | pages = nfs_scan_dirty(mapping, wbc, &head); |
1514 | if (pages != 0) { | 1413 | if (pages != 0) { |
1515 | spin_unlock(&nfsi->req_lock); | 1414 | spin_unlock(&nfsi->req_lock); |
1516 | if (how & FLUSH_INVALIDATE) | 1415 | if (how & FLUSH_INVALIDATE) { |
1517 | nfs_cancel_dirty_list(&head); | 1416 | nfs_cancel_dirty_list(&head); |
1518 | else | 1417 | ret = pages; |
1418 | } else | ||
1519 | ret = nfs_flush_list(inode, &head, pages, how); | 1419 | ret = nfs_flush_list(inode, &head, pages, how); |
1520 | spin_lock(&nfsi->req_lock); | 1420 | spin_lock(&nfsi->req_lock); |
1521 | continue; | 1421 | continue; |
1522 | } | 1422 | } |
1423 | if (wbc->pages_skipped != 0) | ||
1424 | continue; | ||
1523 | if (nocommit) | 1425 | if (nocommit) |
1524 | break; | 1426 | break; |
1525 | pages = nfs_scan_commit(inode, &head, idx_start, npages); | 1427 | pages = nfs_scan_commit(inode, &head, idx_start, npages); |
1526 | if (pages == 0) | 1428 | if (pages == 0) { |
1429 | if (wbc->pages_skipped != 0) | ||
1430 | continue; | ||
1527 | break; | 1431 | break; |
1432 | } | ||
1528 | if (how & FLUSH_INVALIDATE) { | 1433 | if (how & FLUSH_INVALIDATE) { |
1529 | spin_unlock(&nfsi->req_lock); | 1434 | spin_unlock(&nfsi->req_lock); |
1530 | nfs_cancel_commit_list(&head); | 1435 | nfs_cancel_commit_list(&head); |
1436 | ret = pages; | ||
1531 | spin_lock(&nfsi->req_lock); | 1437 | spin_lock(&nfsi->req_lock); |
1532 | continue; | 1438 | continue; |
1533 | } | 1439 | } |
@@ -1540,6 +1446,106 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, | |||
1540 | return ret; | 1446 | return ret; |
1541 | } | 1447 | } |
1542 | 1448 | ||
1449 | /* | ||
1450 | * flush the inode to disk. | ||
1451 | */ | ||
1452 | int nfs_wb_all(struct inode *inode) | ||
1453 | { | ||
1454 | struct address_space *mapping = inode->i_mapping; | ||
1455 | struct writeback_control wbc = { | ||
1456 | .bdi = mapping->backing_dev_info, | ||
1457 | .sync_mode = WB_SYNC_ALL, | ||
1458 | .nr_to_write = LONG_MAX, | ||
1459 | .for_writepages = 1, | ||
1460 | .range_cyclic = 1, | ||
1461 | }; | ||
1462 | int ret; | ||
1463 | |||
1464 | ret = generic_writepages(mapping, &wbc); | ||
1465 | if (ret < 0) | ||
1466 | goto out; | ||
1467 | ret = nfs_sync_mapping_wait(mapping, &wbc, 0); | ||
1468 | if (ret >= 0) | ||
1469 | return 0; | ||
1470 | out: | ||
1471 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
1472 | return ret; | ||
1473 | } | ||
1474 | |||
1475 | int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, loff_t range_end, int how) | ||
1476 | { | ||
1477 | struct writeback_control wbc = { | ||
1478 | .bdi = mapping->backing_dev_info, | ||
1479 | .sync_mode = WB_SYNC_ALL, | ||
1480 | .nr_to_write = LONG_MAX, | ||
1481 | .range_start = range_start, | ||
1482 | .range_end = range_end, | ||
1483 | .for_writepages = 1, | ||
1484 | }; | ||
1485 | int ret; | ||
1486 | |||
1487 | if (!(how & FLUSH_NOWRITEPAGE)) { | ||
1488 | ret = generic_writepages(mapping, &wbc); | ||
1489 | if (ret < 0) | ||
1490 | goto out; | ||
1491 | } | ||
1492 | ret = nfs_sync_mapping_wait(mapping, &wbc, how); | ||
1493 | if (ret >= 0) | ||
1494 | return 0; | ||
1495 | out: | ||
1496 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
1497 | return ret; | ||
1498 | } | ||
1499 | |||
1500 | int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) | ||
1501 | { | ||
1502 | loff_t range_start = page_offset(page); | ||
1503 | loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); | ||
1504 | struct writeback_control wbc = { | ||
1505 | .bdi = page->mapping->backing_dev_info, | ||
1506 | .sync_mode = WB_SYNC_ALL, | ||
1507 | .nr_to_write = LONG_MAX, | ||
1508 | .range_start = range_start, | ||
1509 | .range_end = range_end, | ||
1510 | }; | ||
1511 | int ret; | ||
1512 | |||
1513 | BUG_ON(!PageLocked(page)); | ||
1514 | if (!(how & FLUSH_NOWRITEPAGE) && clear_page_dirty_for_io(page)) { | ||
1515 | ret = nfs_writepage_locked(page, &wbc); | ||
1516 | if (ret < 0) | ||
1517 | goto out; | ||
1518 | } | ||
1519 | ret = nfs_sync_mapping_wait(page->mapping, &wbc, how); | ||
1520 | if (ret >= 0) | ||
1521 | return 0; | ||
1522 | out: | ||
1523 | __mark_inode_dirty(inode, I_DIRTY_PAGES); | ||
1524 | return ret; | ||
1525 | } | ||
1526 | |||
1527 | /* | ||
1528 | * Write back all requests on one page - we do this before reading it. | ||
1529 | */ | ||
1530 | int nfs_wb_page(struct inode *inode, struct page* page) | ||
1531 | { | ||
1532 | return nfs_wb_page_priority(inode, page, FLUSH_STABLE); | ||
1533 | } | ||
1534 | |||
1535 | int nfs_set_page_dirty(struct page *page) | ||
1536 | { | ||
1537 | struct nfs_page *req; | ||
1538 | |||
1539 | req = nfs_page_find_request(page); | ||
1540 | if (req != NULL) { | ||
1541 | /* Mark any existing write requests for flushing */ | ||
1542 | set_bit(PG_NEED_FLUSH, &req->wb_flags); | ||
1543 | nfs_release_request(req); | ||
1544 | } | ||
1545 | return __set_page_dirty_nobuffers(page); | ||
1546 | } | ||
1547 | |||
1548 | |||
1543 | int __init nfs_init_writepagecache(void) | 1549 | int __init nfs_init_writepagecache(void) |
1544 | { | 1550 | { |
1545 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", | 1551 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index f37df46d2eaa..248dd92e6a56 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -787,15 +787,20 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, | |||
787 | key.ex_dentry = dentry; | 787 | key.ex_dentry = dentry; |
788 | 788 | ||
789 | exp = svc_export_lookup(&key); | 789 | exp = svc_export_lookup(&key); |
790 | if (exp != NULL) | 790 | if (exp != NULL) { |
791 | switch (cache_check(&svc_export_cache, &exp->h, reqp)) { | 791 | int err; |
792 | |||
793 | err = cache_check(&svc_export_cache, &exp->h, reqp); | ||
794 | switch (err) { | ||
792 | case 0: break; | 795 | case 0: break; |
793 | case -EAGAIN: | 796 | case -EAGAIN: |
794 | exp = ERR_PTR(-EAGAIN); | 797 | case -ETIMEDOUT: |
798 | exp = ERR_PTR(err); | ||
795 | break; | 799 | break; |
796 | default: | 800 | default: |
797 | exp = NULL; | 801 | exp = NULL; |
798 | } | 802 | } |
803 | } | ||
799 | 804 | ||
800 | return exp; | 805 | return exp; |
801 | } | 806 | } |
@@ -950,6 +955,8 @@ exp_export(struct nfsctl_export *nxp) | |||
950 | 955 | ||
951 | exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); | 956 | exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); |
952 | 957 | ||
958 | memset(&new, 0, sizeof(new)); | ||
959 | |||
953 | /* must make sure there won't be an ex_fsid clash */ | 960 | /* must make sure there won't be an ex_fsid clash */ |
954 | if ((nxp->ex_flags & NFSEXP_FSID) && | 961 | if ((nxp->ex_flags & NFSEXP_FSID) && |
955 | (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && | 962 | (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && |
@@ -980,6 +987,9 @@ exp_export(struct nfsctl_export *nxp) | |||
980 | 987 | ||
981 | new.h.expiry_time = NEVER; | 988 | new.h.expiry_time = NEVER; |
982 | new.h.flags = 0; | 989 | new.h.flags = 0; |
990 | new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); | ||
991 | if (!new.ex_path) | ||
992 | goto finish; | ||
983 | new.ex_client = clp; | 993 | new.ex_client = clp; |
984 | new.ex_mnt = nd.mnt; | 994 | new.ex_mnt = nd.mnt; |
985 | new.ex_dentry = nd.dentry; | 995 | new.ex_dentry = nd.dentry; |
@@ -1000,10 +1010,11 @@ exp_export(struct nfsctl_export *nxp) | |||
1000 | /* failed to create at least one index */ | 1010 | /* failed to create at least one index */ |
1001 | exp_do_unexport(exp); | 1011 | exp_do_unexport(exp); |
1002 | cache_flush(); | 1012 | cache_flush(); |
1003 | err = -ENOMEM; | 1013 | } else |
1004 | } | 1014 | err = 0; |
1005 | |||
1006 | finish: | 1015 | finish: |
1016 | if (new.ex_path) | ||
1017 | kfree(new.ex_path); | ||
1007 | if (exp) | 1018 | if (exp) |
1008 | exp_put(exp); | 1019 | exp_put(exp); |
1009 | if (fsid_key && !IS_ERR(fsid_key)) | 1020 | if (fsid_key && !IS_ERR(fsid_key)) |
@@ -1104,6 +1115,10 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) | |||
1104 | path, nd.dentry, clp->name, | 1115 | path, nd.dentry, clp->name, |
1105 | inode->i_sb->s_id, inode->i_ino); | 1116 | inode->i_sb->s_id, inode->i_ino); |
1106 | exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); | 1117 | exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); |
1118 | if (IS_ERR(exp)) { | ||
1119 | err = PTR_ERR(exp); | ||
1120 | goto out; | ||
1121 | } | ||
1107 | if (!exp) { | 1122 | if (!exp) { |
1108 | dprintk("nfsd: exp_rootfh export not found.\n"); | 1123 | dprintk("nfsd: exp_rootfh export not found.\n"); |
1109 | goto out; | 1124 | goto out; |
@@ -1159,12 +1174,10 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, | |||
1159 | mk_fsid_v1(fsidv, 0); | 1174 | mk_fsid_v1(fsidv, 0); |
1160 | 1175 | ||
1161 | exp = exp_find(clp, 1, fsidv, creq); | 1176 | exp = exp_find(clp, 1, fsidv, creq); |
1162 | if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN) | 1177 | if (IS_ERR(exp)) |
1163 | return nfserr_dropit; | 1178 | return nfserrno(PTR_ERR(exp)); |
1164 | if (exp == NULL) | 1179 | if (exp == NULL) |
1165 | return nfserr_perm; | 1180 | return nfserr_perm; |
1166 | else if (IS_ERR(exp)) | ||
1167 | return nfserrno(PTR_ERR(exp)); | ||
1168 | rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); | 1181 | rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); |
1169 | exp_put(exp); | 1182 | exp_put(exp); |
1170 | return rv; | 1183 | return rv; |
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 11fdaf7721b4..221acd1f11f6 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c | |||
@@ -22,7 +22,7 @@ | |||
22 | /* | 22 | /* |
23 | * Note: we hold the dentry use count while the file is open. | 23 | * Note: we hold the dentry use count while the file is open. |
24 | */ | 24 | */ |
25 | static u32 | 25 | static __be32 |
26 | nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) | 26 | nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) |
27 | { | 27 | { |
28 | __be32 nfserr; | 28 | __be32 nfserr; |
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index e3eca0816986..edde5dc5f796 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
@@ -222,12 +222,10 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | |||
222 | { | 222 | { |
223 | struct dentry *dentry = resp->fh.fh_dentry; | 223 | struct dentry *dentry = resp->fh.fh_dentry; |
224 | struct inode *inode = dentry->d_inode; | 224 | struct inode *inode = dentry->d_inode; |
225 | int w = nfsacl_size( | ||
226 | (resp->mask & NFS_ACL) ? resp->acl_access : NULL, | ||
227 | (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); | ||
228 | struct kvec *head = rqstp->rq_res.head; | 225 | struct kvec *head = rqstp->rq_res.head; |
229 | unsigned int base; | 226 | unsigned int base; |
230 | int n; | 227 | int n; |
228 | int w; | ||
231 | 229 | ||
232 | if (dentry == NULL || dentry->d_inode == NULL) | 230 | if (dentry == NULL || dentry->d_inode == NULL) |
233 | return 0; | 231 | return 0; |
@@ -239,7 +237,9 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | |||
239 | return 0; | 237 | return 0; |
240 | base = (char *)p - (char *)head->iov_base; | 238 | base = (char *)p - (char *)head->iov_base; |
241 | 239 | ||
242 | rqstp->rq_res.page_len = w; | 240 | rqstp->rq_res.page_len = w = nfsacl_size( |
241 | (resp->mask & NFS_ACL) ? resp->acl_access : NULL, | ||
242 | (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); | ||
243 | while (w > 0) { | 243 | while (w > 0) { |
244 | if (!rqstp->rq_respages[rqstp->rq_resused++]) | 244 | if (!rqstp->rq_respages[rqstp->rq_resused++]) |
245 | return 0; | 245 | return 0; |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index fcad2895ddb0..3e3f2de82c36 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
@@ -171,19 +171,19 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | |||
171 | p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); | 171 | p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); |
172 | if (resp->status == 0 && dentry && dentry->d_inode) { | 172 | if (resp->status == 0 && dentry && dentry->d_inode) { |
173 | struct inode *inode = dentry->d_inode; | 173 | struct inode *inode = dentry->d_inode; |
174 | int w = nfsacl_size( | ||
175 | (resp->mask & NFS_ACL) ? resp->acl_access : NULL, | ||
176 | (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); | ||
177 | struct kvec *head = rqstp->rq_res.head; | 174 | struct kvec *head = rqstp->rq_res.head; |
178 | unsigned int base; | 175 | unsigned int base; |
179 | int n; | 176 | int n; |
177 | int w; | ||
180 | 178 | ||
181 | *p++ = htonl(resp->mask); | 179 | *p++ = htonl(resp->mask); |
182 | if (!xdr_ressize_check(rqstp, p)) | 180 | if (!xdr_ressize_check(rqstp, p)) |
183 | return 0; | 181 | return 0; |
184 | base = (char *)p - (char *)head->iov_base; | 182 | base = (char *)p - (char *)head->iov_base; |
185 | 183 | ||
186 | rqstp->rq_res.page_len = w; | 184 | rqstp->rq_res.page_len = w = nfsacl_size( |
185 | (resp->mask & NFS_ACL) ? resp->acl_access : NULL, | ||
186 | (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); | ||
187 | while (w > 0) { | 187 | while (w > 0) { |
188 | if (!rqstp->rq_respages[rqstp->rq_resused++]) | 188 | if (!rqstp->rq_respages[rqstp->rq_resused++]) |
189 | return 0; | 189 | return 0; |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index b4baca3053c3..277df40f098d 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -24,10 +24,6 @@ | |||
24 | 24 | ||
25 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 25 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
26 | 26 | ||
27 | #ifdef NFSD_OPTIMIZE_SPACE | ||
28 | # define inline | ||
29 | #endif | ||
30 | |||
31 | 27 | ||
32 | /* | 28 | /* |
33 | * Mapping of S_IF* types to NFS file types | 29 | * Mapping of S_IF* types to NFS file types |
@@ -42,14 +38,14 @@ static u32 nfs3_ftypes[] = { | |||
42 | /* | 38 | /* |
43 | * XDR functions for basic NFS types | 39 | * XDR functions for basic NFS types |
44 | */ | 40 | */ |
45 | static inline __be32 * | 41 | static __be32 * |
46 | encode_time3(__be32 *p, struct timespec *time) | 42 | encode_time3(__be32 *p, struct timespec *time) |
47 | { | 43 | { |
48 | *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); | 44 | *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); |
49 | return p; | 45 | return p; |
50 | } | 46 | } |
51 | 47 | ||
52 | static inline __be32 * | 48 | static __be32 * |
53 | decode_time3(__be32 *p, struct timespec *time) | 49 | decode_time3(__be32 *p, struct timespec *time) |
54 | { | 50 | { |
55 | time->tv_sec = ntohl(*p++); | 51 | time->tv_sec = ntohl(*p++); |
@@ -57,7 +53,7 @@ decode_time3(__be32 *p, struct timespec *time) | |||
57 | return p; | 53 | return p; |
58 | } | 54 | } |
59 | 55 | ||
60 | static inline __be32 * | 56 | static __be32 * |
61 | decode_fh(__be32 *p, struct svc_fh *fhp) | 57 | decode_fh(__be32 *p, struct svc_fh *fhp) |
62 | { | 58 | { |
63 | unsigned int size; | 59 | unsigned int size; |
@@ -77,7 +73,7 @@ __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp) | |||
77 | return decode_fh(p, fhp); | 73 | return decode_fh(p, fhp); |
78 | } | 74 | } |
79 | 75 | ||
80 | static inline __be32 * | 76 | static __be32 * |
81 | encode_fh(__be32 *p, struct svc_fh *fhp) | 77 | encode_fh(__be32 *p, struct svc_fh *fhp) |
82 | { | 78 | { |
83 | unsigned int size = fhp->fh_handle.fh_size; | 79 | unsigned int size = fhp->fh_handle.fh_size; |
@@ -91,7 +87,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
91 | * Decode a file name and make sure that the path contains | 87 | * Decode a file name and make sure that the path contains |
92 | * no slashes or null bytes. | 88 | * no slashes or null bytes. |
93 | */ | 89 | */ |
94 | static inline __be32 * | 90 | static __be32 * |
95 | decode_filename(__be32 *p, char **namp, int *lenp) | 91 | decode_filename(__be32 *p, char **namp, int *lenp) |
96 | { | 92 | { |
97 | char *name; | 93 | char *name; |
@@ -107,7 +103,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) | |||
107 | return p; | 103 | return p; |
108 | } | 104 | } |
109 | 105 | ||
110 | static inline __be32 * | 106 | static __be32 * |
111 | decode_sattr3(__be32 *p, struct iattr *iap) | 107 | decode_sattr3(__be32 *p, struct iattr *iap) |
112 | { | 108 | { |
113 | u32 tmp; | 109 | u32 tmp; |
@@ -153,7 +149,7 @@ decode_sattr3(__be32 *p, struct iattr *iap) | |||
153 | return p; | 149 | return p; |
154 | } | 150 | } |
155 | 151 | ||
156 | static inline __be32 * | 152 | static __be32 * |
157 | encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | 153 | encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, |
158 | struct kstat *stat) | 154 | struct kstat *stat) |
159 | { | 155 | { |
@@ -186,7 +182,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | |||
186 | return p; | 182 | return p; |
187 | } | 183 | } |
188 | 184 | ||
189 | static inline __be32 * | 185 | static __be32 * |
190 | encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) | 186 | encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) |
191 | { | 187 | { |
192 | struct inode *inode = fhp->fh_dentry->d_inode; | 188 | struct inode *inode = fhp->fh_dentry->d_inode; |
@@ -776,7 +772,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, | |||
776 | return xdr_ressize_check(rqstp, p); | 772 | return xdr_ressize_check(rqstp, p); |
777 | } | 773 | } |
778 | 774 | ||
779 | static inline __be32 * | 775 | static __be32 * |
780 | encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | 776 | encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, |
781 | int namlen, ino_t ino) | 777 | int namlen, ino_t ino) |
782 | { | 778 | { |
@@ -790,7 +786,7 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | |||
790 | return p; | 786 | return p; |
791 | } | 787 | } |
792 | 788 | ||
793 | static inline __be32 * | 789 | static __be32 * |
794 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, | 790 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, |
795 | struct svc_fh *fhp) | 791 | struct svc_fh *fhp) |
796 | { | 792 | { |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 50bc94243ca1..8522729830db 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -33,13 +33,6 @@ | |||
33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | * | ||
37 | * Note: some routines in this file are just trivial wrappers | ||
38 | * (e.g. nfsd4_lookup()) defined solely for the sake of consistent | ||
39 | * naming. Since all such routines have been declared "inline", | ||
40 | * there shouldn't be any associated overhead. At some point in | ||
41 | * the future, I might inline these "by hand" to clean up a | ||
42 | * little. | ||
43 | */ | 36 | */ |
44 | 37 | ||
45 | #include <linux/param.h> | 38 | #include <linux/param.h> |
@@ -161,8 +154,9 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ | |||
161 | } | 154 | } |
162 | 155 | ||
163 | 156 | ||
164 | static inline __be32 | 157 | static __be32 |
165 | nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner) | 158 | nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
159 | struct nfsd4_open *open) | ||
166 | { | 160 | { |
167 | __be32 status; | 161 | __be32 status; |
168 | dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", | 162 | dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", |
@@ -179,11 +173,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
179 | status = nfsd4_process_open1(open); | 173 | status = nfsd4_process_open1(open); |
180 | if (status == nfserr_replay_me) { | 174 | if (status == nfserr_replay_me) { |
181 | struct nfs4_replay *rp = &open->op_stateowner->so_replay; | 175 | struct nfs4_replay *rp = &open->op_stateowner->so_replay; |
182 | fh_put(current_fh); | 176 | fh_put(&cstate->current_fh); |
183 | current_fh->fh_handle.fh_size = rp->rp_openfh_len; | 177 | cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len; |
184 | memcpy(¤t_fh->fh_handle.fh_base, rp->rp_openfh, | 178 | memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh, |
185 | rp->rp_openfh_len); | 179 | rp->rp_openfh_len); |
186 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 180 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
187 | if (status) | 181 | if (status) |
188 | dprintk("nfsd4_open: replay failed" | 182 | dprintk("nfsd4_open: replay failed" |
189 | " restoring previous filehandle\n"); | 183 | " restoring previous filehandle\n"); |
@@ -215,7 +209,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
215 | * (3) set open->op_truncate if the file is to be | 209 | * (3) set open->op_truncate if the file is to be |
216 | * truncated after opening, (4) do permission checking. | 210 | * truncated after opening, (4) do permission checking. |
217 | */ | 211 | */ |
218 | status = do_open_lookup(rqstp, current_fh, open); | 212 | status = do_open_lookup(rqstp, &cstate->current_fh, |
213 | open); | ||
219 | if (status) | 214 | if (status) |
220 | goto out; | 215 | goto out; |
221 | break; | 216 | break; |
@@ -227,7 +222,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
227 | * open->op_truncate if the file is to be truncated | 222 | * open->op_truncate if the file is to be truncated |
228 | * after opening, (3) do permission checking. | 223 | * after opening, (3) do permission checking. |
229 | */ | 224 | */ |
230 | status = do_open_fhandle(rqstp, current_fh, open); | 225 | status = do_open_fhandle(rqstp, &cstate->current_fh, |
226 | open); | ||
231 | if (status) | 227 | if (status) |
232 | goto out; | 228 | goto out; |
233 | break; | 229 | break; |
@@ -248,11 +244,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
248 | * successful, it (1) truncates the file if open->op_truncate was | 244 | * successful, it (1) truncates the file if open->op_truncate was |
249 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. | 245 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. |
250 | */ | 246 | */ |
251 | status = nfsd4_process_open2(rqstp, current_fh, open); | 247 | status = nfsd4_process_open2(rqstp, &cstate->current_fh, open); |
252 | out: | 248 | out: |
253 | if (open->op_stateowner) { | 249 | if (open->op_stateowner) { |
254 | nfs4_get_stateowner(open->op_stateowner); | 250 | nfs4_get_stateowner(open->op_stateowner); |
255 | *replay_owner = open->op_stateowner; | 251 | cstate->replay_owner = open->op_stateowner; |
256 | } | 252 | } |
257 | nfs4_unlock_state(); | 253 | nfs4_unlock_state(); |
258 | return status; | 254 | return status; |
@@ -261,71 +257,80 @@ out: | |||
261 | /* | 257 | /* |
262 | * filehandle-manipulating ops. | 258 | * filehandle-manipulating ops. |
263 | */ | 259 | */ |
264 | static inline __be32 | 260 | static __be32 |
265 | nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh) | 261 | nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
262 | struct svc_fh **getfh) | ||
266 | { | 263 | { |
267 | if (!current_fh->fh_dentry) | 264 | if (!cstate->current_fh.fh_dentry) |
268 | return nfserr_nofilehandle; | 265 | return nfserr_nofilehandle; |
269 | 266 | ||
270 | *getfh = current_fh; | 267 | *getfh = &cstate->current_fh; |
271 | return nfs_ok; | 268 | return nfs_ok; |
272 | } | 269 | } |
273 | 270 | ||
274 | static inline __be32 | 271 | static __be32 |
275 | nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh) | 272 | nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
273 | struct nfsd4_putfh *putfh) | ||
276 | { | 274 | { |
277 | fh_put(current_fh); | 275 | fh_put(&cstate->current_fh); |
278 | current_fh->fh_handle.fh_size = putfh->pf_fhlen; | 276 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; |
279 | memcpy(¤t_fh->fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen); | 277 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, |
280 | return fh_verify(rqstp, current_fh, 0, MAY_NOP); | 278 | putfh->pf_fhlen); |
279 | return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); | ||
281 | } | 280 | } |
282 | 281 | ||
283 | static inline __be32 | 282 | static __be32 |
284 | nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) | 283 | nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
284 | void *arg) | ||
285 | { | 285 | { |
286 | __be32 status; | 286 | __be32 status; |
287 | 287 | ||
288 | fh_put(current_fh); | 288 | fh_put(&cstate->current_fh); |
289 | status = exp_pseudoroot(rqstp->rq_client, current_fh, | 289 | status = exp_pseudoroot(rqstp->rq_client, &cstate->current_fh, |
290 | &rqstp->rq_chandle); | 290 | &rqstp->rq_chandle); |
291 | return status; | 291 | return status; |
292 | } | 292 | } |
293 | 293 | ||
294 | static inline __be32 | 294 | static __be32 |
295 | nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh) | 295 | nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
296 | void *arg) | ||
296 | { | 297 | { |
297 | if (!save_fh->fh_dentry) | 298 | if (!cstate->save_fh.fh_dentry) |
298 | return nfserr_restorefh; | 299 | return nfserr_restorefh; |
299 | 300 | ||
300 | fh_dup2(current_fh, save_fh); | 301 | fh_dup2(&cstate->current_fh, &cstate->save_fh); |
301 | return nfs_ok; | 302 | return nfs_ok; |
302 | } | 303 | } |
303 | 304 | ||
304 | static inline __be32 | 305 | static __be32 |
305 | nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh) | 306 | nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
307 | void *arg) | ||
306 | { | 308 | { |
307 | if (!current_fh->fh_dentry) | 309 | if (!cstate->current_fh.fh_dentry) |
308 | return nfserr_nofilehandle; | 310 | return nfserr_nofilehandle; |
309 | 311 | ||
310 | fh_dup2(save_fh, current_fh); | 312 | fh_dup2(&cstate->save_fh, &cstate->current_fh); |
311 | return nfs_ok; | 313 | return nfs_ok; |
312 | } | 314 | } |
313 | 315 | ||
314 | /* | 316 | /* |
315 | * misc nfsv4 ops | 317 | * misc nfsv4 ops |
316 | */ | 318 | */ |
317 | static inline __be32 | 319 | static __be32 |
318 | nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access) | 320 | nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
321 | struct nfsd4_access *access) | ||
319 | { | 322 | { |
320 | if (access->ac_req_access & ~NFS3_ACCESS_FULL) | 323 | if (access->ac_req_access & ~NFS3_ACCESS_FULL) |
321 | return nfserr_inval; | 324 | return nfserr_inval; |
322 | 325 | ||
323 | access->ac_resp_access = access->ac_req_access; | 326 | access->ac_resp_access = access->ac_req_access; |
324 | return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported); | 327 | return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access, |
328 | &access->ac_supported); | ||
325 | } | 329 | } |
326 | 330 | ||
327 | static inline __be32 | 331 | static __be32 |
328 | nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit) | 332 | nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
333 | struct nfsd4_commit *commit) | ||
329 | { | 334 | { |
330 | __be32 status; | 335 | __be32 status; |
331 | 336 | ||
@@ -333,14 +338,16 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com | |||
333 | *p++ = nfssvc_boot.tv_sec; | 338 | *p++ = nfssvc_boot.tv_sec; |
334 | *p++ = nfssvc_boot.tv_usec; | 339 | *p++ = nfssvc_boot.tv_usec; |
335 | 340 | ||
336 | status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count); | 341 | status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, |
342 | commit->co_count); | ||
337 | if (status == nfserr_symlink) | 343 | if (status == nfserr_symlink) |
338 | status = nfserr_inval; | 344 | status = nfserr_inval; |
339 | return status; | 345 | return status; |
340 | } | 346 | } |
341 | 347 | ||
342 | static __be32 | 348 | static __be32 |
343 | nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create) | 349 | nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
350 | struct nfsd4_create *create) | ||
344 | { | 351 | { |
345 | struct svc_fh resfh; | 352 | struct svc_fh resfh; |
346 | __be32 status; | 353 | __be32 status; |
@@ -348,7 +355,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
348 | 355 | ||
349 | fh_init(&resfh, NFS4_FHSIZE); | 356 | fh_init(&resfh, NFS4_FHSIZE); |
350 | 357 | ||
351 | status = fh_verify(rqstp, current_fh, S_IFDIR, MAY_CREATE); | 358 | status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE); |
352 | if (status == nfserr_symlink) | 359 | if (status == nfserr_symlink) |
353 | status = nfserr_notdir; | 360 | status = nfserr_notdir; |
354 | if (status) | 361 | if (status) |
@@ -365,9 +372,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
365 | */ | 372 | */ |
366 | create->cr_linkname[create->cr_linklen] = 0; | 373 | create->cr_linkname[create->cr_linklen] = 0; |
367 | 374 | ||
368 | status = nfsd_symlink(rqstp, current_fh, create->cr_name, | 375 | status = nfsd_symlink(rqstp, &cstate->current_fh, |
369 | create->cr_namelen, create->cr_linkname, | 376 | create->cr_name, create->cr_namelen, |
370 | create->cr_linklen, &resfh, &create->cr_iattr); | 377 | create->cr_linkname, create->cr_linklen, |
378 | &resfh, &create->cr_iattr); | ||
371 | break; | 379 | break; |
372 | 380 | ||
373 | case NF4BLK: | 381 | case NF4BLK: |
@@ -375,9 +383,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
375 | if (MAJOR(rdev) != create->cr_specdata1 || | 383 | if (MAJOR(rdev) != create->cr_specdata1 || |
376 | MINOR(rdev) != create->cr_specdata2) | 384 | MINOR(rdev) != create->cr_specdata2) |
377 | return nfserr_inval; | 385 | return nfserr_inval; |
378 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 386 | status = nfsd_create(rqstp, &cstate->current_fh, |
379 | create->cr_namelen, &create->cr_iattr, | 387 | create->cr_name, create->cr_namelen, |
380 | S_IFBLK, rdev, &resfh); | 388 | &create->cr_iattr, S_IFBLK, rdev, &resfh); |
381 | break; | 389 | break; |
382 | 390 | ||
383 | case NF4CHR: | 391 | case NF4CHR: |
@@ -385,28 +393,28 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
385 | if (MAJOR(rdev) != create->cr_specdata1 || | 393 | if (MAJOR(rdev) != create->cr_specdata1 || |
386 | MINOR(rdev) != create->cr_specdata2) | 394 | MINOR(rdev) != create->cr_specdata2) |
387 | return nfserr_inval; | 395 | return nfserr_inval; |
388 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 396 | status = nfsd_create(rqstp, &cstate->current_fh, |
389 | create->cr_namelen, &create->cr_iattr, | 397 | create->cr_name, create->cr_namelen, |
390 | S_IFCHR, rdev, &resfh); | 398 | &create->cr_iattr,S_IFCHR, rdev, &resfh); |
391 | break; | 399 | break; |
392 | 400 | ||
393 | case NF4SOCK: | 401 | case NF4SOCK: |
394 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 402 | status = nfsd_create(rqstp, &cstate->current_fh, |
395 | create->cr_namelen, &create->cr_iattr, | 403 | create->cr_name, create->cr_namelen, |
396 | S_IFSOCK, 0, &resfh); | 404 | &create->cr_iattr, S_IFSOCK, 0, &resfh); |
397 | break; | 405 | break; |
398 | 406 | ||
399 | case NF4FIFO: | 407 | case NF4FIFO: |
400 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 408 | status = nfsd_create(rqstp, &cstate->current_fh, |
401 | create->cr_namelen, &create->cr_iattr, | 409 | create->cr_name, create->cr_namelen, |
402 | S_IFIFO, 0, &resfh); | 410 | &create->cr_iattr, S_IFIFO, 0, &resfh); |
403 | break; | 411 | break; |
404 | 412 | ||
405 | case NF4DIR: | 413 | case NF4DIR: |
406 | create->cr_iattr.ia_valid &= ~ATTR_SIZE; | 414 | create->cr_iattr.ia_valid &= ~ATTR_SIZE; |
407 | status = nfsd_create(rqstp, current_fh, create->cr_name, | 415 | status = nfsd_create(rqstp, &cstate->current_fh, |
408 | create->cr_namelen, &create->cr_iattr, | 416 | create->cr_name, create->cr_namelen, |
409 | S_IFDIR, 0, &resfh); | 417 | &create->cr_iattr, S_IFDIR, 0, &resfh); |
410 | break; | 418 | break; |
411 | 419 | ||
412 | default: | 420 | default: |
@@ -414,21 +422,22 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre | |||
414 | } | 422 | } |
415 | 423 | ||
416 | if (!status) { | 424 | if (!status) { |
417 | fh_unlock(current_fh); | 425 | fh_unlock(&cstate->current_fh); |
418 | set_change_info(&create->cr_cinfo, current_fh); | 426 | set_change_info(&create->cr_cinfo, &cstate->current_fh); |
419 | fh_dup2(current_fh, &resfh); | 427 | fh_dup2(&cstate->current_fh, &resfh); |
420 | } | 428 | } |
421 | 429 | ||
422 | fh_put(&resfh); | 430 | fh_put(&resfh); |
423 | return status; | 431 | return status; |
424 | } | 432 | } |
425 | 433 | ||
426 | static inline __be32 | 434 | static __be32 |
427 | nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr) | 435 | nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
436 | struct nfsd4_getattr *getattr) | ||
428 | { | 437 | { |
429 | __be32 status; | 438 | __be32 status; |
430 | 439 | ||
431 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 440 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
432 | if (status) | 441 | if (status) |
433 | return status; | 442 | return status; |
434 | 443 | ||
@@ -438,26 +447,28 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge | |||
438 | getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; | 447 | getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; |
439 | getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; | 448 | getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; |
440 | 449 | ||
441 | getattr->ga_fhp = current_fh; | 450 | getattr->ga_fhp = &cstate->current_fh; |
442 | return nfs_ok; | 451 | return nfs_ok; |
443 | } | 452 | } |
444 | 453 | ||
445 | static inline __be32 | 454 | static __be32 |
446 | nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh, | 455 | nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
447 | struct svc_fh *save_fh, struct nfsd4_link *link) | 456 | struct nfsd4_link *link) |
448 | { | 457 | { |
449 | __be32 status = nfserr_nofilehandle; | 458 | __be32 status = nfserr_nofilehandle; |
450 | 459 | ||
451 | if (!save_fh->fh_dentry) | 460 | if (!cstate->save_fh.fh_dentry) |
452 | return status; | 461 | return status; |
453 | status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh); | 462 | status = nfsd_link(rqstp, &cstate->current_fh, |
463 | link->li_name, link->li_namelen, &cstate->save_fh); | ||
454 | if (!status) | 464 | if (!status) |
455 | set_change_info(&link->li_cinfo, current_fh); | 465 | set_change_info(&link->li_cinfo, &cstate->current_fh); |
456 | return status; | 466 | return status; |
457 | } | 467 | } |
458 | 468 | ||
459 | static __be32 | 469 | static __be32 |
460 | nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) | 470 | nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
471 | void *arg) | ||
461 | { | 472 | { |
462 | struct svc_fh tmp_fh; | 473 | struct svc_fh tmp_fh; |
463 | __be32 ret; | 474 | __be32 ret; |
@@ -466,22 +477,27 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh) | |||
466 | if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, | 477 | if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, |
467 | &rqstp->rq_chandle)) != 0) | 478 | &rqstp->rq_chandle)) != 0) |
468 | return ret; | 479 | return ret; |
469 | if (tmp_fh.fh_dentry == current_fh->fh_dentry) { | 480 | if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { |
470 | fh_put(&tmp_fh); | 481 | fh_put(&tmp_fh); |
471 | return nfserr_noent; | 482 | return nfserr_noent; |
472 | } | 483 | } |
473 | fh_put(&tmp_fh); | 484 | fh_put(&tmp_fh); |
474 | return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh); | 485 | return nfsd_lookup(rqstp, &cstate->current_fh, |
486 | "..", 2, &cstate->current_fh); | ||
475 | } | 487 | } |
476 | 488 | ||
477 | static inline __be32 | 489 | static __be32 |
478 | nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup) | 490 | nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
491 | struct nfsd4_lookup *lookup) | ||
479 | { | 492 | { |
480 | return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh); | 493 | return nfsd_lookup(rqstp, &cstate->current_fh, |
494 | lookup->lo_name, lookup->lo_len, | ||
495 | &cstate->current_fh); | ||
481 | } | 496 | } |
482 | 497 | ||
483 | static inline __be32 | 498 | static __be32 |
484 | nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) | 499 | nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
500 | struct nfsd4_read *read) | ||
485 | { | 501 | { |
486 | __be32 status; | 502 | __be32 status; |
487 | 503 | ||
@@ -493,7 +509,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read | |||
493 | 509 | ||
494 | nfs4_lock_state(); | 510 | nfs4_lock_state(); |
495 | /* check stateid */ | 511 | /* check stateid */ |
496 | if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, | 512 | if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh, |
513 | &read->rd_stateid, | ||
497 | CHECK_FH | RD_STATE, &read->rd_filp))) { | 514 | CHECK_FH | RD_STATE, &read->rd_filp))) { |
498 | dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); | 515 | dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); |
499 | goto out; | 516 | goto out; |
@@ -504,12 +521,13 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read | |||
504 | out: | 521 | out: |
505 | nfs4_unlock_state(); | 522 | nfs4_unlock_state(); |
506 | read->rd_rqstp = rqstp; | 523 | read->rd_rqstp = rqstp; |
507 | read->rd_fhp = current_fh; | 524 | read->rd_fhp = &cstate->current_fh; |
508 | return status; | 525 | return status; |
509 | } | 526 | } |
510 | 527 | ||
511 | static inline __be32 | 528 | static __be32 |
512 | nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) | 529 | nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
530 | struct nfsd4_readdir *readdir) | ||
513 | { | 531 | { |
514 | u64 cookie = readdir->rd_cookie; | 532 | u64 cookie = readdir->rd_cookie; |
515 | static const nfs4_verifier zeroverf; | 533 | static const nfs4_verifier zeroverf; |
@@ -527,48 +545,51 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re | |||
527 | return nfserr_bad_cookie; | 545 | return nfserr_bad_cookie; |
528 | 546 | ||
529 | readdir->rd_rqstp = rqstp; | 547 | readdir->rd_rqstp = rqstp; |
530 | readdir->rd_fhp = current_fh; | 548 | readdir->rd_fhp = &cstate->current_fh; |
531 | return nfs_ok; | 549 | return nfs_ok; |
532 | } | 550 | } |
533 | 551 | ||
534 | static inline __be32 | 552 | static __be32 |
535 | nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink) | 553 | nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
554 | struct nfsd4_readlink *readlink) | ||
536 | { | 555 | { |
537 | readlink->rl_rqstp = rqstp; | 556 | readlink->rl_rqstp = rqstp; |
538 | readlink->rl_fhp = current_fh; | 557 | readlink->rl_fhp = &cstate->current_fh; |
539 | return nfs_ok; | 558 | return nfs_ok; |
540 | } | 559 | } |
541 | 560 | ||
542 | static inline __be32 | 561 | static __be32 |
543 | nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove) | 562 | nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
563 | struct nfsd4_remove *remove) | ||
544 | { | 564 | { |
545 | __be32 status; | 565 | __be32 status; |
546 | 566 | ||
547 | if (nfs4_in_grace()) | 567 | if (nfs4_in_grace()) |
548 | return nfserr_grace; | 568 | return nfserr_grace; |
549 | status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen); | 569 | status = nfsd_unlink(rqstp, &cstate->current_fh, 0, |
570 | remove->rm_name, remove->rm_namelen); | ||
550 | if (status == nfserr_symlink) | 571 | if (status == nfserr_symlink) |
551 | return nfserr_notdir; | 572 | return nfserr_notdir; |
552 | if (!status) { | 573 | if (!status) { |
553 | fh_unlock(current_fh); | 574 | fh_unlock(&cstate->current_fh); |
554 | set_change_info(&remove->rm_cinfo, current_fh); | 575 | set_change_info(&remove->rm_cinfo, &cstate->current_fh); |
555 | } | 576 | } |
556 | return status; | 577 | return status; |
557 | } | 578 | } |
558 | 579 | ||
559 | static inline __be32 | 580 | static __be32 |
560 | nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, | 581 | nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
561 | struct svc_fh *save_fh, struct nfsd4_rename *rename) | 582 | struct nfsd4_rename *rename) |
562 | { | 583 | { |
563 | __be32 status = nfserr_nofilehandle; | 584 | __be32 status = nfserr_nofilehandle; |
564 | 585 | ||
565 | if (!save_fh->fh_dentry) | 586 | if (!cstate->save_fh.fh_dentry) |
566 | return status; | 587 | return status; |
567 | if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags | 588 | if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags |
568 | & NFSEXP_NOSUBTREECHECK)) | 589 | & NFSEXP_NOSUBTREECHECK)) |
569 | return nfserr_grace; | 590 | return nfserr_grace; |
570 | status = nfsd_rename(rqstp, save_fh, rename->rn_sname, | 591 | status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, |
571 | rename->rn_snamelen, current_fh, | 592 | rename->rn_snamelen, &cstate->current_fh, |
572 | rename->rn_tname, rename->rn_tnamelen); | 593 | rename->rn_tname, rename->rn_tnamelen); |
573 | 594 | ||
574 | /* the underlying filesystem returns different error's than required | 595 | /* the underlying filesystem returns different error's than required |
@@ -576,27 +597,28 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh, | |||
576 | if (status == nfserr_isdir) | 597 | if (status == nfserr_isdir) |
577 | status = nfserr_exist; | 598 | status = nfserr_exist; |
578 | else if ((status == nfserr_notdir) && | 599 | else if ((status == nfserr_notdir) && |
579 | (S_ISDIR(save_fh->fh_dentry->d_inode->i_mode) && | 600 | (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && |
580 | S_ISDIR(current_fh->fh_dentry->d_inode->i_mode))) | 601 | S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) |
581 | status = nfserr_exist; | 602 | status = nfserr_exist; |
582 | else if (status == nfserr_symlink) | 603 | else if (status == nfserr_symlink) |
583 | status = nfserr_notdir; | 604 | status = nfserr_notdir; |
584 | 605 | ||
585 | if (!status) { | 606 | if (!status) { |
586 | set_change_info(&rename->rn_sinfo, current_fh); | 607 | set_change_info(&rename->rn_sinfo, &cstate->current_fh); |
587 | set_change_info(&rename->rn_tinfo, save_fh); | 608 | set_change_info(&rename->rn_tinfo, &cstate->save_fh); |
588 | } | 609 | } |
589 | return status; | 610 | return status; |
590 | } | 611 | } |
591 | 612 | ||
592 | static inline __be32 | 613 | static __be32 |
593 | nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) | 614 | nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
615 | struct nfsd4_setattr *setattr) | ||
594 | { | 616 | { |
595 | __be32 status = nfs_ok; | 617 | __be32 status = nfs_ok; |
596 | 618 | ||
597 | if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { | 619 | if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { |
598 | nfs4_lock_state(); | 620 | nfs4_lock_state(); |
599 | status = nfs4_preprocess_stateid_op(current_fh, | 621 | status = nfs4_preprocess_stateid_op(&cstate->current_fh, |
600 | &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); | 622 | &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL); |
601 | nfs4_unlock_state(); | 623 | nfs4_unlock_state(); |
602 | if (status) { | 624 | if (status) { |
@@ -606,16 +628,18 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se | |||
606 | } | 628 | } |
607 | status = nfs_ok; | 629 | status = nfs_ok; |
608 | if (setattr->sa_acl != NULL) | 630 | if (setattr->sa_acl != NULL) |
609 | status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl); | 631 | status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, |
632 | setattr->sa_acl); | ||
610 | if (status) | 633 | if (status) |
611 | return status; | 634 | return status; |
612 | status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, | 635 | status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, |
613 | 0, (time_t)0); | 636 | 0, (time_t)0); |
614 | return status; | 637 | return status; |
615 | } | 638 | } |
616 | 639 | ||
617 | static inline __be32 | 640 | static __be32 |
618 | nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) | 641 | nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
642 | struct nfsd4_write *write) | ||
619 | { | 643 | { |
620 | stateid_t *stateid = &write->wr_stateid; | 644 | stateid_t *stateid = &write->wr_stateid; |
621 | struct file *filp = NULL; | 645 | struct file *filp = NULL; |
@@ -628,7 +652,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
628 | return nfserr_inval; | 652 | return nfserr_inval; |
629 | 653 | ||
630 | nfs4_lock_state(); | 654 | nfs4_lock_state(); |
631 | status = nfs4_preprocess_stateid_op(current_fh, stateid, | 655 | status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid, |
632 | CHECK_FH | WR_STATE, &filp); | 656 | CHECK_FH | WR_STATE, &filp); |
633 | if (filp) | 657 | if (filp) |
634 | get_file(filp); | 658 | get_file(filp); |
@@ -645,9 +669,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
645 | *p++ = nfssvc_boot.tv_sec; | 669 | *p++ = nfssvc_boot.tv_sec; |
646 | *p++ = nfssvc_boot.tv_usec; | 670 | *p++ = nfssvc_boot.tv_usec; |
647 | 671 | ||
648 | status = nfsd_write(rqstp, current_fh, filp, write->wr_offset, | 672 | status = nfsd_write(rqstp, &cstate->current_fh, filp, |
649 | rqstp->rq_vec, write->wr_vlen, write->wr_buflen, | 673 | write->wr_offset, rqstp->rq_vec, write->wr_vlen, |
650 | &write->wr_how_written); | 674 | write->wr_buflen, &write->wr_how_written); |
651 | if (filp) | 675 | if (filp) |
652 | fput(filp); | 676 | fput(filp); |
653 | 677 | ||
@@ -662,13 +686,14 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ | |||
662 | * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. | 686 | * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK. |
663 | */ | 687 | */ |
664 | static __be32 | 688 | static __be32 |
665 | nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify) | 689 | _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
690 | struct nfsd4_verify *verify) | ||
666 | { | 691 | { |
667 | __be32 *buf, *p; | 692 | __be32 *buf, *p; |
668 | int count; | 693 | int count; |
669 | __be32 status; | 694 | __be32 status; |
670 | 695 | ||
671 | status = fh_verify(rqstp, current_fh, 0, MAY_NOP); | 696 | status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP); |
672 | if (status) | 697 | if (status) |
673 | return status; | 698 | return status; |
674 | 699 | ||
@@ -689,8 +714,9 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver | |||
689 | if (!buf) | 714 | if (!buf) |
690 | return nfserr_resource; | 715 | return nfserr_resource; |
691 | 716 | ||
692 | status = nfsd4_encode_fattr(current_fh, current_fh->fh_export, | 717 | status = nfsd4_encode_fattr(&cstate->current_fh, |
693 | current_fh->fh_dentry, buf, | 718 | cstate->current_fh.fh_export, |
719 | cstate->current_fh.fh_dentry, buf, | ||
694 | &count, verify->ve_bmval, | 720 | &count, verify->ve_bmval, |
695 | rqstp); | 721 | rqstp); |
696 | 722 | ||
@@ -712,6 +738,26 @@ out_kfree: | |||
712 | return status; | 738 | return status; |
713 | } | 739 | } |
714 | 740 | ||
741 | static __be32 | ||
742 | nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
743 | struct nfsd4_verify *verify) | ||
744 | { | ||
745 | __be32 status; | ||
746 | |||
747 | status = _nfsd4_verify(rqstp, cstate, verify); | ||
748 | return status == nfserr_not_same ? nfs_ok : status; | ||
749 | } | ||
750 | |||
751 | static __be32 | ||
752 | nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
753 | struct nfsd4_verify *verify) | ||
754 | { | ||
755 | __be32 status; | ||
756 | |||
757 | status = _nfsd4_verify(rqstp, cstate, verify); | ||
758 | return status == nfserr_same ? nfs_ok : status; | ||
759 | } | ||
760 | |||
715 | /* | 761 | /* |
716 | * NULL call. | 762 | * NULL call. |
717 | */ | 763 | */ |
@@ -727,6 +773,42 @@ static inline void nfsd4_increment_op_stats(u32 opnum) | |||
727 | nfsdstats.nfs4_opcount[opnum]++; | 773 | nfsdstats.nfs4_opcount[opnum]++; |
728 | } | 774 | } |
729 | 775 | ||
776 | static void cstate_free(struct nfsd4_compound_state *cstate) | ||
777 | { | ||
778 | if (cstate == NULL) | ||
779 | return; | ||
780 | fh_put(&cstate->current_fh); | ||
781 | fh_put(&cstate->save_fh); | ||
782 | BUG_ON(cstate->replay_owner); | ||
783 | kfree(cstate); | ||
784 | } | ||
785 | |||
786 | static struct nfsd4_compound_state *cstate_alloc(void) | ||
787 | { | ||
788 | struct nfsd4_compound_state *cstate; | ||
789 | |||
790 | cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL); | ||
791 | if (cstate == NULL) | ||
792 | return NULL; | ||
793 | fh_init(&cstate->current_fh, NFS4_FHSIZE); | ||
794 | fh_init(&cstate->save_fh, NFS4_FHSIZE); | ||
795 | cstate->replay_owner = NULL; | ||
796 | return cstate; | ||
797 | } | ||
798 | |||
799 | typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, | ||
800 | void *); | ||
801 | |||
802 | struct nfsd4_operation { | ||
803 | nfsd4op_func op_func; | ||
804 | u32 op_flags; | ||
805 | /* Most ops require a valid current filehandle; a few don't: */ | ||
806 | #define ALLOWED_WITHOUT_FH 1 | ||
807 | /* GETATTR and ops not listed as returning NFS4ERR_MOVED: */ | ||
808 | #define ALLOWED_ON_ABSENT_FS 2 | ||
809 | }; | ||
810 | |||
811 | static struct nfsd4_operation nfsd4_ops[]; | ||
730 | 812 | ||
731 | /* | 813 | /* |
732 | * COMPOUND call. | 814 | * COMPOUND call. |
@@ -737,21 +819,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
737 | struct nfsd4_compoundres *resp) | 819 | struct nfsd4_compoundres *resp) |
738 | { | 820 | { |
739 | struct nfsd4_op *op; | 821 | struct nfsd4_op *op; |
740 | struct svc_fh *current_fh = NULL; | 822 | struct nfsd4_operation *opdesc; |
741 | struct svc_fh *save_fh = NULL; | 823 | struct nfsd4_compound_state *cstate = NULL; |
742 | struct nfs4_stateowner *replay_owner = NULL; | 824 | int slack_bytes; |
743 | int slack_space; /* in words, not bytes! */ | ||
744 | __be32 status; | 825 | __be32 status; |
745 | 826 | ||
746 | status = nfserr_resource; | 827 | status = nfserr_resource; |
747 | current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL); | 828 | cstate = cstate_alloc(); |
748 | if (current_fh == NULL) | 829 | if (cstate == NULL) |
749 | goto out; | ||
750 | fh_init(current_fh, NFS4_FHSIZE); | ||
751 | save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL); | ||
752 | if (save_fh == NULL) | ||
753 | goto out; | 830 | goto out; |
754 | fh_init(save_fh, NFS4_FHSIZE); | ||
755 | 831 | ||
756 | resp->xbuf = &rqstp->rq_res; | 832 | resp->xbuf = &rqstp->rq_res; |
757 | resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; | 833 | resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; |
@@ -790,164 +866,44 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
790 | * failed response to the next operation. If we don't | 866 | * failed response to the next operation. If we don't |
791 | * have enough room, fail with ERR_RESOURCE. | 867 | * have enough room, fail with ERR_RESOURCE. |
792 | */ | 868 | */ |
793 | /* FIXME - is slack_space *really* words, or bytes??? - neilb */ | 869 | slack_bytes = (char *)resp->end - (char *)resp->p; |
794 | slack_space = (char *)resp->end - (char *)resp->p; | 870 | if (slack_bytes < COMPOUND_SLACK_SPACE |
795 | if (slack_space < COMPOUND_SLACK_SPACE + COMPOUND_ERR_SLACK_SPACE) { | 871 | + COMPOUND_ERR_SLACK_SPACE) { |
796 | BUG_ON(slack_space < COMPOUND_ERR_SLACK_SPACE); | 872 | BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE); |
797 | op->status = nfserr_resource; | 873 | op->status = nfserr_resource; |
798 | goto encode_op; | 874 | goto encode_op; |
799 | } | 875 | } |
800 | 876 | ||
801 | /* All operations except RENEW, SETCLIENTID, RESTOREFH | 877 | opdesc = &nfsd4_ops[op->opnum]; |
802 | * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH | 878 | |
803 | * require a valid current filehandle | 879 | if (!cstate->current_fh.fh_dentry) { |
804 | */ | 880 | if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { |
805 | if (!current_fh->fh_dentry) { | ||
806 | if (!((op->opnum == OP_PUTFH) || | ||
807 | (op->opnum == OP_PUTROOTFH) || | ||
808 | (op->opnum == OP_SETCLIENTID) || | ||
809 | (op->opnum == OP_SETCLIENTID_CONFIRM) || | ||
810 | (op->opnum == OP_RENEW) || | ||
811 | (op->opnum == OP_RESTOREFH) || | ||
812 | (op->opnum == OP_RELEASE_LOCKOWNER))) { | ||
813 | op->status = nfserr_nofilehandle; | 881 | op->status = nfserr_nofilehandle; |
814 | goto encode_op; | 882 | goto encode_op; |
815 | } | 883 | } |
816 | } | 884 | } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && |
817 | /* Check must be done at start of each operation, except | 885 | !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { |
818 | * for GETATTR and ops not listed as returning NFS4ERR_MOVED | ||
819 | */ | ||
820 | else if (current_fh->fh_export->ex_fslocs.migrated && | ||
821 | !((op->opnum == OP_GETATTR) || | ||
822 | (op->opnum == OP_PUTROOTFH) || | ||
823 | (op->opnum == OP_PUTPUBFH) || | ||
824 | (op->opnum == OP_RENEW) || | ||
825 | (op->opnum == OP_SETCLIENTID) || | ||
826 | (op->opnum == OP_RELEASE_LOCKOWNER))) { | ||
827 | op->status = nfserr_moved; | 886 | op->status = nfserr_moved; |
828 | goto encode_op; | 887 | goto encode_op; |
829 | } | 888 | } |
830 | switch (op->opnum) { | 889 | |
831 | case OP_ACCESS: | 890 | if (opdesc->op_func) |
832 | op->status = nfsd4_access(rqstp, current_fh, &op->u.access); | 891 | op->status = opdesc->op_func(rqstp, cstate, &op->u); |
833 | break; | 892 | else |
834 | case OP_CLOSE: | ||
835 | op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner); | ||
836 | break; | ||
837 | case OP_COMMIT: | ||
838 | op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit); | ||
839 | break; | ||
840 | case OP_CREATE: | ||
841 | op->status = nfsd4_create(rqstp, current_fh, &op->u.create); | ||
842 | break; | ||
843 | case OP_DELEGRETURN: | ||
844 | op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn); | ||
845 | break; | ||
846 | case OP_GETATTR: | ||
847 | op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr); | ||
848 | break; | ||
849 | case OP_GETFH: | ||
850 | op->status = nfsd4_getfh(current_fh, &op->u.getfh); | ||
851 | break; | ||
852 | case OP_LINK: | ||
853 | op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link); | ||
854 | break; | ||
855 | case OP_LOCK: | ||
856 | op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner); | ||
857 | break; | ||
858 | case OP_LOCKT: | ||
859 | op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt); | ||
860 | break; | ||
861 | case OP_LOCKU: | ||
862 | op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner); | ||
863 | break; | ||
864 | case OP_LOOKUP: | ||
865 | op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup); | ||
866 | break; | ||
867 | case OP_LOOKUPP: | ||
868 | op->status = nfsd4_lookupp(rqstp, current_fh); | ||
869 | break; | ||
870 | case OP_NVERIFY: | ||
871 | op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify); | ||
872 | if (op->status == nfserr_not_same) | ||
873 | op->status = nfs_ok; | ||
874 | break; | ||
875 | case OP_OPEN: | ||
876 | op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner); | ||
877 | break; | ||
878 | case OP_OPEN_CONFIRM: | ||
879 | op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner); | ||
880 | break; | ||
881 | case OP_OPEN_DOWNGRADE: | ||
882 | op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner); | ||
883 | break; | ||
884 | case OP_PUTFH: | ||
885 | op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh); | ||
886 | break; | ||
887 | case OP_PUTROOTFH: | ||
888 | op->status = nfsd4_putrootfh(rqstp, current_fh); | ||
889 | break; | ||
890 | case OP_READ: | ||
891 | op->status = nfsd4_read(rqstp, current_fh, &op->u.read); | ||
892 | break; | ||
893 | case OP_READDIR: | ||
894 | op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir); | ||
895 | break; | ||
896 | case OP_READLINK: | ||
897 | op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink); | ||
898 | break; | ||
899 | case OP_REMOVE: | ||
900 | op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove); | ||
901 | break; | ||
902 | case OP_RENAME: | ||
903 | op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename); | ||
904 | break; | ||
905 | case OP_RENEW: | ||
906 | op->status = nfsd4_renew(&op->u.renew); | ||
907 | break; | ||
908 | case OP_RESTOREFH: | ||
909 | op->status = nfsd4_restorefh(current_fh, save_fh); | ||
910 | break; | ||
911 | case OP_SAVEFH: | ||
912 | op->status = nfsd4_savefh(current_fh, save_fh); | ||
913 | break; | ||
914 | case OP_SETATTR: | ||
915 | op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr); | ||
916 | break; | ||
917 | case OP_SETCLIENTID: | ||
918 | op->status = nfsd4_setclientid(rqstp, &op->u.setclientid); | ||
919 | break; | ||
920 | case OP_SETCLIENTID_CONFIRM: | ||
921 | op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm); | ||
922 | break; | ||
923 | case OP_VERIFY: | ||
924 | op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify); | ||
925 | if (op->status == nfserr_same) | ||
926 | op->status = nfs_ok; | ||
927 | break; | ||
928 | case OP_WRITE: | ||
929 | op->status = nfsd4_write(rqstp, current_fh, &op->u.write); | ||
930 | break; | ||
931 | case OP_RELEASE_LOCKOWNER: | ||
932 | op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner); | ||
933 | break; | ||
934 | default: | ||
935 | BUG_ON(op->status == nfs_ok); | 893 | BUG_ON(op->status == nfs_ok); |
936 | break; | ||
937 | } | ||
938 | 894 | ||
939 | encode_op: | 895 | encode_op: |
940 | if (op->status == nfserr_replay_me) { | 896 | if (op->status == nfserr_replay_me) { |
941 | op->replay = &replay_owner->so_replay; | 897 | op->replay = &cstate->replay_owner->so_replay; |
942 | nfsd4_encode_replay(resp, op); | 898 | nfsd4_encode_replay(resp, op); |
943 | status = op->status = op->replay->rp_status; | 899 | status = op->status = op->replay->rp_status; |
944 | } else { | 900 | } else { |
945 | nfsd4_encode_operation(resp, op); | 901 | nfsd4_encode_operation(resp, op); |
946 | status = op->status; | 902 | status = op->status; |
947 | } | 903 | } |
948 | if (replay_owner && (replay_owner != (void *)(-1))) { | 904 | if (cstate->replay_owner) { |
949 | nfs4_put_stateowner(replay_owner); | 905 | nfs4_put_stateowner(cstate->replay_owner); |
950 | replay_owner = NULL; | 906 | cstate->replay_owner = NULL; |
951 | } | 907 | } |
952 | /* XXX Ugh, we need to get rid of this kind of special case: */ | 908 | /* XXX Ugh, we need to get rid of this kind of special case: */ |
953 | if (op->opnum == OP_READ && op->u.read.rd_filp) | 909 | if (op->opnum == OP_READ && op->u.read.rd_filp) |
@@ -958,15 +914,124 @@ encode_op: | |||
958 | 914 | ||
959 | out: | 915 | out: |
960 | nfsd4_release_compoundargs(args); | 916 | nfsd4_release_compoundargs(args); |
961 | if (current_fh) | 917 | cstate_free(cstate); |
962 | fh_put(current_fh); | ||
963 | kfree(current_fh); | ||
964 | if (save_fh) | ||
965 | fh_put(save_fh); | ||
966 | kfree(save_fh); | ||
967 | return status; | 918 | return status; |
968 | } | 919 | } |
969 | 920 | ||
921 | static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = { | ||
922 | [OP_ACCESS] = { | ||
923 | .op_func = (nfsd4op_func)nfsd4_access, | ||
924 | }, | ||
925 | [OP_CLOSE] = { | ||
926 | .op_func = (nfsd4op_func)nfsd4_close, | ||
927 | }, | ||
928 | [OP_COMMIT] = { | ||
929 | .op_func = (nfsd4op_func)nfsd4_commit, | ||
930 | }, | ||
931 | [OP_CREATE] = { | ||
932 | .op_func = (nfsd4op_func)nfsd4_create, | ||
933 | }, | ||
934 | [OP_DELEGRETURN] = { | ||
935 | .op_func = (nfsd4op_func)nfsd4_delegreturn, | ||
936 | }, | ||
937 | [OP_GETATTR] = { | ||
938 | .op_func = (nfsd4op_func)nfsd4_getattr, | ||
939 | .op_flags = ALLOWED_ON_ABSENT_FS, | ||
940 | }, | ||
941 | [OP_GETFH] = { | ||
942 | .op_func = (nfsd4op_func)nfsd4_getfh, | ||
943 | }, | ||
944 | [OP_LINK] = { | ||
945 | .op_func = (nfsd4op_func)nfsd4_link, | ||
946 | }, | ||
947 | [OP_LOCK] = { | ||
948 | .op_func = (nfsd4op_func)nfsd4_lock, | ||
949 | }, | ||
950 | [OP_LOCKT] = { | ||
951 | .op_func = (nfsd4op_func)nfsd4_lockt, | ||
952 | }, | ||
953 | [OP_LOCKU] = { | ||
954 | .op_func = (nfsd4op_func)nfsd4_locku, | ||
955 | }, | ||
956 | [OP_LOOKUP] = { | ||
957 | .op_func = (nfsd4op_func)nfsd4_lookup, | ||
958 | }, | ||
959 | [OP_LOOKUPP] = { | ||
960 | .op_func = (nfsd4op_func)nfsd4_lookupp, | ||
961 | }, | ||
962 | [OP_NVERIFY] = { | ||
963 | .op_func = (nfsd4op_func)nfsd4_nverify, | ||
964 | }, | ||
965 | [OP_OPEN] = { | ||
966 | .op_func = (nfsd4op_func)nfsd4_open, | ||
967 | }, | ||
968 | [OP_OPEN_CONFIRM] = { | ||
969 | .op_func = (nfsd4op_func)nfsd4_open_confirm, | ||
970 | }, | ||
971 | [OP_OPEN_DOWNGRADE] = { | ||
972 | .op_func = (nfsd4op_func)nfsd4_open_downgrade, | ||
973 | }, | ||
974 | [OP_PUTFH] = { | ||
975 | .op_func = (nfsd4op_func)nfsd4_putfh, | ||
976 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
977 | }, | ||
978 | [OP_PUTPUBFH] = { | ||
979 | /* unsupported; just for future reference: */ | ||
980 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
981 | }, | ||
982 | [OP_PUTROOTFH] = { | ||
983 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | ||
984 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
985 | }, | ||
986 | [OP_READ] = { | ||
987 | .op_func = (nfsd4op_func)nfsd4_read, | ||
988 | }, | ||
989 | [OP_READDIR] = { | ||
990 | .op_func = (nfsd4op_func)nfsd4_readdir, | ||
991 | }, | ||
992 | [OP_READLINK] = { | ||
993 | .op_func = (nfsd4op_func)nfsd4_readlink, | ||
994 | }, | ||
995 | [OP_REMOVE] = { | ||
996 | .op_func = (nfsd4op_func)nfsd4_remove, | ||
997 | }, | ||
998 | [OP_RENAME] = { | ||
999 | .op_func = (nfsd4op_func)nfsd4_rename, | ||
1000 | }, | ||
1001 | [OP_RENEW] = { | ||
1002 | .op_func = (nfsd4op_func)nfsd4_renew, | ||
1003 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
1004 | }, | ||
1005 | [OP_RESTOREFH] = { | ||
1006 | .op_func = (nfsd4op_func)nfsd4_restorefh, | ||
1007 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
1008 | }, | ||
1009 | [OP_SAVEFH] = { | ||
1010 | .op_func = (nfsd4op_func)nfsd4_savefh, | ||
1011 | }, | ||
1012 | [OP_SETATTR] = { | ||
1013 | .op_func = (nfsd4op_func)nfsd4_setattr, | ||
1014 | }, | ||
1015 | [OP_SETCLIENTID] = { | ||
1016 | .op_func = (nfsd4op_func)nfsd4_setclientid, | ||
1017 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
1018 | }, | ||
1019 | [OP_SETCLIENTID_CONFIRM] = { | ||
1020 | .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, | ||
1021 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
1022 | }, | ||
1023 | [OP_VERIFY] = { | ||
1024 | .op_func = (nfsd4op_func)nfsd4_verify, | ||
1025 | }, | ||
1026 | [OP_WRITE] = { | ||
1027 | .op_func = (nfsd4op_func)nfsd4_write, | ||
1028 | }, | ||
1029 | [OP_RELEASE_LOCKOWNER] = { | ||
1030 | .op_func = (nfsd4op_func)nfsd4_release_lockowner, | ||
1031 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | ||
1032 | }, | ||
1033 | }; | ||
1034 | |||
970 | #define nfs4svc_decode_voidargs NULL | 1035 | #define nfs4svc_decode_voidargs NULL |
971 | #define nfs4svc_release_void NULL | 1036 | #define nfs4svc_release_void NULL |
972 | #define nfsd4_voidres nfsd4_voidargs | 1037 | #define nfsd4_voidres nfsd4_voidargs |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 81b8565d3837..c7774e3a9469 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -259,7 +259,7 @@ nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry) | |||
259 | printk("nfsd4: non-file found in client recovery directory\n"); | 259 | printk("nfsd4: non-file found in client recovery directory\n"); |
260 | return -EINVAL; | 260 | return -EINVAL; |
261 | } | 261 | } |
262 | mutex_lock(&dir->d_inode->i_mutex); | 262 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
263 | status = vfs_unlink(dir->d_inode, dentry); | 263 | status = vfs_unlink(dir->d_inode, dentry); |
264 | mutex_unlock(&dir->d_inode->i_mutex); | 264 | mutex_unlock(&dir->d_inode->i_mutex); |
265 | return status; | 265 | return status; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 293b6495829f..9de89df961f4 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -84,10 +84,10 @@ static void nfs4_set_recdir(char *recdir); | |||
84 | */ | 84 | */ |
85 | static DEFINE_MUTEX(client_mutex); | 85 | static DEFINE_MUTEX(client_mutex); |
86 | 86 | ||
87 | static kmem_cache_t *stateowner_slab = NULL; | 87 | static struct kmem_cache *stateowner_slab = NULL; |
88 | static kmem_cache_t *file_slab = NULL; | 88 | static struct kmem_cache *file_slab = NULL; |
89 | static kmem_cache_t *stateid_slab = NULL; | 89 | static struct kmem_cache *stateid_slab = NULL; |
90 | static kmem_cache_t *deleg_slab = NULL; | 90 | static struct kmem_cache *deleg_slab = NULL; |
91 | 91 | ||
92 | void | 92 | void |
93 | nfs4_lock_state(void) | 93 | nfs4_lock_state(void) |
@@ -711,7 +711,8 @@ out_err: | |||
711 | * | 711 | * |
712 | */ | 712 | */ |
713 | __be32 | 713 | __be32 |
714 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid) | 714 | nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
715 | struct nfsd4_setclientid *setclid) | ||
715 | { | 716 | { |
716 | __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; | 717 | __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; |
717 | struct xdr_netobj clname = { | 718 | struct xdr_netobj clname = { |
@@ -876,7 +877,9 @@ out: | |||
876 | * NOTE: callback information will be processed here in a future patch | 877 | * NOTE: callback information will be processed here in a future patch |
877 | */ | 878 | */ |
878 | __be32 | 879 | __be32 |
879 | nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm) | 880 | nfsd4_setclientid_confirm(struct svc_rqst *rqstp, |
881 | struct nfsd4_compound_state *cstate, | ||
882 | struct nfsd4_setclientid_confirm *setclientid_confirm) | ||
880 | { | 883 | { |
881 | __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; | 884 | __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; |
882 | struct nfs4_client *conf, *unconf; | 885 | struct nfs4_client *conf, *unconf; |
@@ -1003,7 +1006,7 @@ alloc_init_file(struct inode *ino) | |||
1003 | } | 1006 | } |
1004 | 1007 | ||
1005 | static void | 1008 | static void |
1006 | nfsd4_free_slab(kmem_cache_t **slab) | 1009 | nfsd4_free_slab(struct kmem_cache **slab) |
1007 | { | 1010 | { |
1008 | if (*slab == NULL) | 1011 | if (*slab == NULL) |
1009 | return; | 1012 | return; |
@@ -1310,7 +1313,7 @@ static inline void | |||
1310 | nfs4_file_downgrade(struct file *filp, unsigned int share_access) | 1313 | nfs4_file_downgrade(struct file *filp, unsigned int share_access) |
1311 | { | 1314 | { |
1312 | if (share_access & NFS4_SHARE_ACCESS_WRITE) { | 1315 | if (share_access & NFS4_SHARE_ACCESS_WRITE) { |
1313 | put_write_access(filp->f_dentry->d_inode); | 1316 | put_write_access(filp->f_path.dentry->d_inode); |
1314 | filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; | 1317 | filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; |
1315 | } | 1318 | } |
1316 | } | 1319 | } |
@@ -1623,7 +1626,7 @@ static __be32 | |||
1623 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) | 1626 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) |
1624 | { | 1627 | { |
1625 | struct file *filp = stp->st_vfs_file; | 1628 | struct file *filp = stp->st_vfs_file; |
1626 | struct inode *inode = filp->f_dentry->d_inode; | 1629 | struct inode *inode = filp->f_path.dentry->d_inode; |
1627 | unsigned int share_access, new_writer; | 1630 | unsigned int share_access, new_writer; |
1628 | __be32 status; | 1631 | __be32 status; |
1629 | 1632 | ||
@@ -1829,12 +1832,12 @@ out: | |||
1829 | } | 1832 | } |
1830 | 1833 | ||
1831 | static struct workqueue_struct *laundry_wq; | 1834 | static struct workqueue_struct *laundry_wq; |
1832 | static struct work_struct laundromat_work; | 1835 | static void laundromat_main(struct work_struct *); |
1833 | static void laundromat_main(void *); | 1836 | static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main); |
1834 | static DECLARE_WORK(laundromat_work, laundromat_main, NULL); | ||
1835 | 1837 | ||
1836 | __be32 | 1838 | __be32 |
1837 | nfsd4_renew(clientid_t *clid) | 1839 | nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
1840 | clientid_t *clid) | ||
1838 | { | 1841 | { |
1839 | struct nfs4_client *clp; | 1842 | struct nfs4_client *clp; |
1840 | __be32 status; | 1843 | __be32 status; |
@@ -1940,7 +1943,7 @@ nfs4_laundromat(void) | |||
1940 | } | 1943 | } |
1941 | 1944 | ||
1942 | void | 1945 | void |
1943 | laundromat_main(void *not_used) | 1946 | laundromat_main(struct work_struct *not_used) |
1944 | { | 1947 | { |
1945 | time_t t; | 1948 | time_t t; |
1946 | 1949 | ||
@@ -1966,7 +1969,7 @@ search_close_lru(u32 st_id, int flags) | |||
1966 | static inline int | 1969 | static inline int |
1967 | nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp) | 1970 | nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp) |
1968 | { | 1971 | { |
1969 | return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_dentry->d_inode; | 1972 | return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode; |
1970 | } | 1973 | } |
1971 | 1974 | ||
1972 | static int | 1975 | static int |
@@ -2242,24 +2245,25 @@ check_replay: | |||
2242 | } | 2245 | } |
2243 | 2246 | ||
2244 | __be32 | 2247 | __be32 |
2245 | nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner) | 2248 | nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2249 | struct nfsd4_open_confirm *oc) | ||
2246 | { | 2250 | { |
2247 | __be32 status; | 2251 | __be32 status; |
2248 | struct nfs4_stateowner *sop; | 2252 | struct nfs4_stateowner *sop; |
2249 | struct nfs4_stateid *stp; | 2253 | struct nfs4_stateid *stp; |
2250 | 2254 | ||
2251 | dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", | 2255 | dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", |
2252 | (int)current_fh->fh_dentry->d_name.len, | 2256 | (int)cstate->current_fh.fh_dentry->d_name.len, |
2253 | current_fh->fh_dentry->d_name.name); | 2257 | cstate->current_fh.fh_dentry->d_name.name); |
2254 | 2258 | ||
2255 | status = fh_verify(rqstp, current_fh, S_IFREG, 0); | 2259 | status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0); |
2256 | if (status) | 2260 | if (status) |
2257 | return status; | 2261 | return status; |
2258 | 2262 | ||
2259 | nfs4_lock_state(); | 2263 | nfs4_lock_state(); |
2260 | 2264 | ||
2261 | if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid, | 2265 | if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2262 | &oc->oc_req_stateid, | 2266 | oc->oc_seqid, &oc->oc_req_stateid, |
2263 | CHECK_FH | CONFIRM | OPEN_STATE, | 2267 | CHECK_FH | CONFIRM | OPEN_STATE, |
2264 | &oc->oc_stateowner, &stp, NULL))) | 2268 | &oc->oc_stateowner, &stp, NULL))) |
2265 | goto out; | 2269 | goto out; |
@@ -2279,7 +2283,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs | |||
2279 | out: | 2283 | out: |
2280 | if (oc->oc_stateowner) { | 2284 | if (oc->oc_stateowner) { |
2281 | nfs4_get_stateowner(oc->oc_stateowner); | 2285 | nfs4_get_stateowner(oc->oc_stateowner); |
2282 | *replay_owner = oc->oc_stateowner; | 2286 | cstate->replay_owner = oc->oc_stateowner; |
2283 | } | 2287 | } |
2284 | nfs4_unlock_state(); | 2288 | nfs4_unlock_state(); |
2285 | return status; | 2289 | return status; |
@@ -2311,22 +2315,25 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) | |||
2311 | } | 2315 | } |
2312 | 2316 | ||
2313 | __be32 | 2317 | __be32 |
2314 | nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner) | 2318 | nfsd4_open_downgrade(struct svc_rqst *rqstp, |
2319 | struct nfsd4_compound_state *cstate, | ||
2320 | struct nfsd4_open_downgrade *od) | ||
2315 | { | 2321 | { |
2316 | __be32 status; | 2322 | __be32 status; |
2317 | struct nfs4_stateid *stp; | 2323 | struct nfs4_stateid *stp; |
2318 | unsigned int share_access; | 2324 | unsigned int share_access; |
2319 | 2325 | ||
2320 | dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", | 2326 | dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", |
2321 | (int)current_fh->fh_dentry->d_name.len, | 2327 | (int)cstate->current_fh.fh_dentry->d_name.len, |
2322 | current_fh->fh_dentry->d_name.name); | 2328 | cstate->current_fh.fh_dentry->d_name.name); |
2323 | 2329 | ||
2324 | if (!access_valid(od->od_share_access) | 2330 | if (!access_valid(od->od_share_access) |
2325 | || !deny_valid(od->od_share_deny)) | 2331 | || !deny_valid(od->od_share_deny)) |
2326 | return nfserr_inval; | 2332 | return nfserr_inval; |
2327 | 2333 | ||
2328 | nfs4_lock_state(); | 2334 | nfs4_lock_state(); |
2329 | if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, | 2335 | if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2336 | od->od_seqid, | ||
2330 | &od->od_stateid, | 2337 | &od->od_stateid, |
2331 | CHECK_FH | OPEN_STATE, | 2338 | CHECK_FH | OPEN_STATE, |
2332 | &od->od_stateowner, &stp, NULL))) | 2339 | &od->od_stateowner, &stp, NULL))) |
@@ -2356,7 +2363,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n | |||
2356 | out: | 2363 | out: |
2357 | if (od->od_stateowner) { | 2364 | if (od->od_stateowner) { |
2358 | nfs4_get_stateowner(od->od_stateowner); | 2365 | nfs4_get_stateowner(od->od_stateowner); |
2359 | *replay_owner = od->od_stateowner; | 2366 | cstate->replay_owner = od->od_stateowner; |
2360 | } | 2367 | } |
2361 | nfs4_unlock_state(); | 2368 | nfs4_unlock_state(); |
2362 | return status; | 2369 | return status; |
@@ -2366,18 +2373,20 @@ out: | |||
2366 | * nfs4_unlock_state() called after encode | 2373 | * nfs4_unlock_state() called after encode |
2367 | */ | 2374 | */ |
2368 | __be32 | 2375 | __be32 |
2369 | nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner) | 2376 | nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2377 | struct nfsd4_close *close) | ||
2370 | { | 2378 | { |
2371 | __be32 status; | 2379 | __be32 status; |
2372 | struct nfs4_stateid *stp; | 2380 | struct nfs4_stateid *stp; |
2373 | 2381 | ||
2374 | dprintk("NFSD: nfsd4_close on file %.*s\n", | 2382 | dprintk("NFSD: nfsd4_close on file %.*s\n", |
2375 | (int)current_fh->fh_dentry->d_name.len, | 2383 | (int)cstate->current_fh.fh_dentry->d_name.len, |
2376 | current_fh->fh_dentry->d_name.name); | 2384 | cstate->current_fh.fh_dentry->d_name.name); |
2377 | 2385 | ||
2378 | nfs4_lock_state(); | 2386 | nfs4_lock_state(); |
2379 | /* check close_lru for replay */ | 2387 | /* check close_lru for replay */ |
2380 | if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, | 2388 | if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2389 | close->cl_seqid, | ||
2381 | &close->cl_stateid, | 2390 | &close->cl_stateid, |
2382 | CHECK_FH | OPEN_STATE | CLOSE_STATE, | 2391 | CHECK_FH | OPEN_STATE | CLOSE_STATE, |
2383 | &close->cl_stateowner, &stp, NULL))) | 2392 | &close->cl_stateowner, &stp, NULL))) |
@@ -2398,22 +2407,24 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos | |||
2398 | out: | 2407 | out: |
2399 | if (close->cl_stateowner) { | 2408 | if (close->cl_stateowner) { |
2400 | nfs4_get_stateowner(close->cl_stateowner); | 2409 | nfs4_get_stateowner(close->cl_stateowner); |
2401 | *replay_owner = close->cl_stateowner; | 2410 | cstate->replay_owner = close->cl_stateowner; |
2402 | } | 2411 | } |
2403 | nfs4_unlock_state(); | 2412 | nfs4_unlock_state(); |
2404 | return status; | 2413 | return status; |
2405 | } | 2414 | } |
2406 | 2415 | ||
2407 | __be32 | 2416 | __be32 |
2408 | nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr) | 2417 | nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2418 | struct nfsd4_delegreturn *dr) | ||
2409 | { | 2419 | { |
2410 | __be32 status; | 2420 | __be32 status; |
2411 | 2421 | ||
2412 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) | 2422 | if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) |
2413 | goto out; | 2423 | goto out; |
2414 | 2424 | ||
2415 | nfs4_lock_state(); | 2425 | nfs4_lock_state(); |
2416 | status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET, NULL); | 2426 | status = nfs4_preprocess_stateid_op(&cstate->current_fh, |
2427 | &dr->dr_stateid, DELEG_RET, NULL); | ||
2417 | nfs4_unlock_state(); | 2428 | nfs4_unlock_state(); |
2418 | out: | 2429 | out: |
2419 | return status; | 2430 | return status; |
@@ -2636,7 +2647,8 @@ check_lock_length(u64 offset, u64 length) | |||
2636 | * LOCK operation | 2647 | * LOCK operation |
2637 | */ | 2648 | */ |
2638 | __be32 | 2649 | __be32 |
2639 | nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner) | 2650 | nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2651 | struct nfsd4_lock *lock) | ||
2640 | { | 2652 | { |
2641 | struct nfs4_stateowner *open_sop = NULL; | 2653 | struct nfs4_stateowner *open_sop = NULL; |
2642 | struct nfs4_stateowner *lock_sop = NULL; | 2654 | struct nfs4_stateowner *lock_sop = NULL; |
@@ -2655,7 +2667,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2655 | if (check_lock_length(lock->lk_offset, lock->lk_length)) | 2667 | if (check_lock_length(lock->lk_offset, lock->lk_length)) |
2656 | return nfserr_inval; | 2668 | return nfserr_inval; |
2657 | 2669 | ||
2658 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) { | 2670 | if ((status = fh_verify(rqstp, &cstate->current_fh, |
2671 | S_IFREG, MAY_LOCK))) { | ||
2659 | dprintk("NFSD: nfsd4_lock: permission denied!\n"); | 2672 | dprintk("NFSD: nfsd4_lock: permission denied!\n"); |
2660 | return status; | 2673 | return status; |
2661 | } | 2674 | } |
@@ -2676,7 +2689,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2676 | goto out; | 2689 | goto out; |
2677 | 2690 | ||
2678 | /* validate and update open stateid and open seqid */ | 2691 | /* validate and update open stateid and open seqid */ |
2679 | status = nfs4_preprocess_seqid_op(current_fh, | 2692 | status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2680 | lock->lk_new_open_seqid, | 2693 | lock->lk_new_open_seqid, |
2681 | &lock->lk_new_open_stateid, | 2694 | &lock->lk_new_open_stateid, |
2682 | CHECK_FH | OPEN_STATE, | 2695 | CHECK_FH | OPEN_STATE, |
@@ -2703,7 +2716,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2703 | goto out; | 2716 | goto out; |
2704 | } else { | 2717 | } else { |
2705 | /* lock (lock owner + lock stateid) already exists */ | 2718 | /* lock (lock owner + lock stateid) already exists */ |
2706 | status = nfs4_preprocess_seqid_op(current_fh, | 2719 | status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2707 | lock->lk_old_lock_seqid, | 2720 | lock->lk_old_lock_seqid, |
2708 | &lock->lk_old_lock_stateid, | 2721 | &lock->lk_old_lock_stateid, |
2709 | CHECK_FH | LOCK_STATE, | 2722 | CHECK_FH | LOCK_STATE, |
@@ -2760,7 +2773,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2760 | conflock.fl_ops = NULL; | 2773 | conflock.fl_ops = NULL; |
2761 | conflock.fl_lmops = NULL; | 2774 | conflock.fl_lmops = NULL; |
2762 | err = posix_lock_file_conf(filp, &file_lock, &conflock); | 2775 | err = posix_lock_file_conf(filp, &file_lock, &conflock); |
2763 | dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status); | ||
2764 | switch (-err) { | 2776 | switch (-err) { |
2765 | case 0: /* success! */ | 2777 | case 0: /* success! */ |
2766 | update_stateid(&lock_stp->st_stateid); | 2778 | update_stateid(&lock_stp->st_stateid); |
@@ -2786,7 +2798,7 @@ out: | |||
2786 | release_stateowner(lock_sop); | 2798 | release_stateowner(lock_sop); |
2787 | if (lock->lk_replay_owner) { | 2799 | if (lock->lk_replay_owner) { |
2788 | nfs4_get_stateowner(lock->lk_replay_owner); | 2800 | nfs4_get_stateowner(lock->lk_replay_owner); |
2789 | *replay_owner = lock->lk_replay_owner; | 2801 | cstate->replay_owner = lock->lk_replay_owner; |
2790 | } | 2802 | } |
2791 | nfs4_unlock_state(); | 2803 | nfs4_unlock_state(); |
2792 | return status; | 2804 | return status; |
@@ -2796,7 +2808,8 @@ out: | |||
2796 | * LOCKT operation | 2808 | * LOCKT operation |
2797 | */ | 2809 | */ |
2798 | __be32 | 2810 | __be32 |
2799 | nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt) | 2811 | nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2812 | struct nfsd4_lockt *lockt) | ||
2800 | { | 2813 | { |
2801 | struct inode *inode; | 2814 | struct inode *inode; |
2802 | struct file file; | 2815 | struct file file; |
@@ -2817,14 +2830,14 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2817 | if (STALE_CLIENTID(&lockt->lt_clientid)) | 2830 | if (STALE_CLIENTID(&lockt->lt_clientid)) |
2818 | goto out; | 2831 | goto out; |
2819 | 2832 | ||
2820 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) { | 2833 | if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) { |
2821 | dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); | 2834 | dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n"); |
2822 | if (status == nfserr_symlink) | 2835 | if (status == nfserr_symlink) |
2823 | status = nfserr_inval; | 2836 | status = nfserr_inval; |
2824 | goto out; | 2837 | goto out; |
2825 | } | 2838 | } |
2826 | 2839 | ||
2827 | inode = current_fh->fh_dentry->d_inode; | 2840 | inode = cstate->current_fh.fh_dentry->d_inode; |
2828 | locks_init_lock(&file_lock); | 2841 | locks_init_lock(&file_lock); |
2829 | switch (lockt->lt_type) { | 2842 | switch (lockt->lt_type) { |
2830 | case NFS4_READ_LT: | 2843 | case NFS4_READ_LT: |
@@ -2863,7 +2876,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2863 | * only the dentry:inode set. | 2876 | * only the dentry:inode set. |
2864 | */ | 2877 | */ |
2865 | memset(&file, 0, sizeof (struct file)); | 2878 | memset(&file, 0, sizeof (struct file)); |
2866 | file.f_dentry = current_fh->fh_dentry; | 2879 | file.f_path.dentry = cstate->current_fh.fh_dentry; |
2867 | 2880 | ||
2868 | status = nfs_ok; | 2881 | status = nfs_ok; |
2869 | if (posix_test_lock(&file, &file_lock, &conflock)) { | 2882 | if (posix_test_lock(&file, &file_lock, &conflock)) { |
@@ -2876,7 +2889,8 @@ out: | |||
2876 | } | 2889 | } |
2877 | 2890 | ||
2878 | __be32 | 2891 | __be32 |
2879 | nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner) | 2892 | nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
2893 | struct nfsd4_locku *locku) | ||
2880 | { | 2894 | { |
2881 | struct nfs4_stateid *stp; | 2895 | struct nfs4_stateid *stp; |
2882 | struct file *filp = NULL; | 2896 | struct file *filp = NULL; |
@@ -2893,7 +2907,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2893 | 2907 | ||
2894 | nfs4_lock_state(); | 2908 | nfs4_lock_state(); |
2895 | 2909 | ||
2896 | if ((status = nfs4_preprocess_seqid_op(current_fh, | 2910 | if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh, |
2897 | locku->lu_seqid, | 2911 | locku->lu_seqid, |
2898 | &locku->lu_stateid, | 2912 | &locku->lu_stateid, |
2899 | CHECK_FH | LOCK_STATE, | 2913 | CHECK_FH | LOCK_STATE, |
@@ -2934,7 +2948,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2934 | out: | 2948 | out: |
2935 | if (locku->lu_stateowner) { | 2949 | if (locku->lu_stateowner) { |
2936 | nfs4_get_stateowner(locku->lu_stateowner); | 2950 | nfs4_get_stateowner(locku->lu_stateowner); |
2937 | *replay_owner = locku->lu_stateowner; | 2951 | cstate->replay_owner = locku->lu_stateowner; |
2938 | } | 2952 | } |
2939 | nfs4_unlock_state(); | 2953 | nfs4_unlock_state(); |
2940 | return status; | 2954 | return status; |
@@ -2953,7 +2967,7 @@ static int | |||
2953 | check_for_locks(struct file *filp, struct nfs4_stateowner *lowner) | 2967 | check_for_locks(struct file *filp, struct nfs4_stateowner *lowner) |
2954 | { | 2968 | { |
2955 | struct file_lock **flpp; | 2969 | struct file_lock **flpp; |
2956 | struct inode *inode = filp->f_dentry->d_inode; | 2970 | struct inode *inode = filp->f_path.dentry->d_inode; |
2957 | int status = 0; | 2971 | int status = 0; |
2958 | 2972 | ||
2959 | lock_kernel(); | 2973 | lock_kernel(); |
@@ -2969,7 +2983,9 @@ out: | |||
2969 | } | 2983 | } |
2970 | 2984 | ||
2971 | __be32 | 2985 | __be32 |
2972 | nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) | 2986 | nfsd4_release_lockowner(struct svc_rqst *rqstp, |
2987 | struct nfsd4_compound_state *cstate, | ||
2988 | struct nfsd4_release_lockowner *rlockowner) | ||
2973 | { | 2989 | { |
2974 | clientid_t *clid = &rlockowner->rl_clientid; | 2990 | clientid_t *clid = &rlockowner->rl_clientid; |
2975 | struct nfs4_stateowner *sop; | 2991 | struct nfs4_stateowner *sop; |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f3f239db04bb..fea46368afb2 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1845,15 +1845,11 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
1845 | 1845 | ||
1846 | exp_get(exp); | 1846 | exp_get(exp); |
1847 | if (d_mountpoint(dentry)) { | 1847 | if (d_mountpoint(dentry)) { |
1848 | if (nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp)) { | 1848 | int err; |
1849 | /* | 1849 | |
1850 | * -EAGAIN is the only error returned from | 1850 | err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); |
1851 | * nfsd_cross_mnt() and it indicates that an | 1851 | if (err) { |
1852 | * up-call has been initiated to fill in the export | 1852 | nfserr = nfserrno(err); |
1853 | * options on exp. When the answer comes back, | ||
1854 | * this call will be retried. | ||
1855 | */ | ||
1856 | nfserr = nfserr_dropit; | ||
1857 | goto out_put; | 1853 | goto out_put; |
1858 | } | 1854 | } |
1859 | 1855 | ||
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 6100bbe27432..f90d70475854 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c | |||
@@ -66,14 +66,13 @@ nfsd_cache_init(void) | |||
66 | printk (KERN_ERR "nfsd: cannot allocate all %d cache entries, only got %d\n", | 66 | printk (KERN_ERR "nfsd: cannot allocate all %d cache entries, only got %d\n", |
67 | CACHESIZE, CACHESIZE-i); | 67 | CACHESIZE, CACHESIZE-i); |
68 | 68 | ||
69 | hash_list = kmalloc (HASHSIZE * sizeof(struct hlist_head), GFP_KERNEL); | 69 | hash_list = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL); |
70 | if (!hash_list) { | 70 | if (!hash_list) { |
71 | nfsd_cache_shutdown(); | 71 | nfsd_cache_shutdown(); |
72 | printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n", | 72 | printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n", |
73 | HASHSIZE * sizeof(struct hlist_head)); | 73 | HASHSIZE * sizeof(struct hlist_head)); |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | memset(hash_list, 0, HASHSIZE * sizeof(struct hlist_head)); | ||
77 | 76 | ||
78 | cache_disabled = 0; | 77 | cache_disabled = 0; |
79 | } | 78 | } |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 39aed901514b..eedf2e3990a9 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -111,7 +111,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { | |||
111 | 111 | ||
112 | static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) | 112 | static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) |
113 | { | 113 | { |
114 | ino_t ino = file->f_dentry->d_inode->i_ino; | 114 | ino_t ino = file->f_path.dentry->d_inode->i_ino; |
115 | char *data; | 115 | char *data; |
116 | ssize_t rv; | 116 | ssize_t rv; |
117 | 117 | ||
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 727ab3bd450d..b06bf9f70efc 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -169,9 +169,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
169 | exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); | 169 | exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle); |
170 | } | 170 | } |
171 | 171 | ||
172 | error = nfserr_dropit; | 172 | if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN |
173 | if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN) | 173 | || PTR_ERR(exp) == -ETIMEDOUT)) { |
174 | error = nfserrno(PTR_ERR(exp)); | ||
174 | goto out; | 175 | goto out; |
176 | } | ||
175 | 177 | ||
176 | error = nfserr_stale; | 178 | error = nfserr_stale; |
177 | if (!exp || IS_ERR(exp)) | 179 | if (!exp || IS_ERR(exp)) |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 56ebb1443e0e..f5243f943996 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -18,11 +18,6 @@ | |||
18 | 18 | ||
19 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 19 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
20 | 20 | ||
21 | |||
22 | #ifdef NFSD_OPTIMIZE_SPACE | ||
23 | # define inline | ||
24 | #endif | ||
25 | |||
26 | /* | 21 | /* |
27 | * Mapping of S_IF* types to NFS file types | 22 | * Mapping of S_IF* types to NFS file types |
28 | */ | 23 | */ |
@@ -55,7 +50,7 @@ __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp) | |||
55 | return decode_fh(p, fhp); | 50 | return decode_fh(p, fhp); |
56 | } | 51 | } |
57 | 52 | ||
58 | static inline __be32 * | 53 | static __be32 * |
59 | encode_fh(__be32 *p, struct svc_fh *fhp) | 54 | encode_fh(__be32 *p, struct svc_fh *fhp) |
60 | { | 55 | { |
61 | memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); | 56 | memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); |
@@ -66,7 +61,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
66 | * Decode a file name and make sure that the path contains | 61 | * Decode a file name and make sure that the path contains |
67 | * no slashes or null bytes. | 62 | * no slashes or null bytes. |
68 | */ | 63 | */ |
69 | static inline __be32 * | 64 | static __be32 * |
70 | decode_filename(__be32 *p, char **namp, int *lenp) | 65 | decode_filename(__be32 *p, char **namp, int *lenp) |
71 | { | 66 | { |
72 | char *name; | 67 | char *name; |
@@ -82,7 +77,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) | |||
82 | return p; | 77 | return p; |
83 | } | 78 | } |
84 | 79 | ||
85 | static inline __be32 * | 80 | static __be32 * |
86 | decode_pathname(__be32 *p, char **namp, int *lenp) | 81 | decode_pathname(__be32 *p, char **namp, int *lenp) |
87 | { | 82 | { |
88 | char *name; | 83 | char *name; |
@@ -98,7 +93,7 @@ decode_pathname(__be32 *p, char **namp, int *lenp) | |||
98 | return p; | 93 | return p; |
99 | } | 94 | } |
100 | 95 | ||
101 | static inline __be32 * | 96 | static __be32 * |
102 | decode_sattr(__be32 *p, struct iattr *iap) | 97 | decode_sattr(__be32 *p, struct iattr *iap) |
103 | { | 98 | { |
104 | u32 tmp, tmp1; | 99 | u32 tmp, tmp1; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index bb4d926e4487..7a79c23aa6d4 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -99,7 +99,7 @@ static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE]; | |||
99 | /* | 99 | /* |
100 | * Called from nfsd_lookup and encode_dirent. Check if we have crossed | 100 | * Called from nfsd_lookup and encode_dirent. Check if we have crossed |
101 | * a mount point. | 101 | * a mount point. |
102 | * Returns -EAGAIN leaving *dpp and *expp unchanged, | 102 | * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged, |
103 | * or nfs_ok having possibly changed *dpp and *expp | 103 | * or nfs_ok having possibly changed *dpp and *expp |
104 | */ | 104 | */ |
105 | int | 105 | int |
@@ -736,10 +736,10 @@ static int | |||
736 | nfsd_sync(struct file *filp) | 736 | nfsd_sync(struct file *filp) |
737 | { | 737 | { |
738 | int err; | 738 | int err; |
739 | struct inode *inode = filp->f_dentry->d_inode; | 739 | struct inode *inode = filp->f_path.dentry->d_inode; |
740 | dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); | 740 | dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name); |
741 | mutex_lock(&inode->i_mutex); | 741 | mutex_lock(&inode->i_mutex); |
742 | err=nfsd_dosync(filp, filp->f_dentry, filp->f_op); | 742 | err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op); |
743 | mutex_unlock(&inode->i_mutex); | 743 | mutex_unlock(&inode->i_mutex); |
744 | 744 | ||
745 | return err; | 745 | return err; |
@@ -845,7 +845,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
845 | int host_err; | 845 | int host_err; |
846 | 846 | ||
847 | err = nfserr_perm; | 847 | err = nfserr_perm; |
848 | inode = file->f_dentry->d_inode; | 848 | inode = file->f_path.dentry->d_inode; |
849 | #ifdef MSNFS | 849 | #ifdef MSNFS |
850 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && | 850 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && |
851 | (!lock_may_read(inode, offset, *count))) | 851 | (!lock_may_read(inode, offset, *count))) |
@@ -883,7 +883,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
883 | nfsdstats.io_read += host_err; | 883 | nfsdstats.io_read += host_err; |
884 | *count = host_err; | 884 | *count = host_err; |
885 | err = 0; | 885 | err = 0; |
886 | fsnotify_access(file->f_dentry); | 886 | fsnotify_access(file->f_path.dentry); |
887 | } else | 887 | } else |
888 | err = nfserrno(host_err); | 888 | err = nfserrno(host_err); |
889 | out: | 889 | out: |
@@ -917,11 +917,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
917 | err = nfserr_perm; | 917 | err = nfserr_perm; |
918 | 918 | ||
919 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && | 919 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && |
920 | (!lock_may_write(file->f_dentry->d_inode, offset, cnt))) | 920 | (!lock_may_write(file->f_path.dentry->d_inode, offset, cnt))) |
921 | goto out; | 921 | goto out; |
922 | #endif | 922 | #endif |
923 | 923 | ||
924 | dentry = file->f_dentry; | 924 | dentry = file->f_path.dentry; |
925 | inode = dentry->d_inode; | 925 | inode = dentry->d_inode; |
926 | exp = fhp->fh_export; | 926 | exp = fhp->fh_export; |
927 | 927 | ||
@@ -950,7 +950,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
950 | set_fs(oldfs); | 950 | set_fs(oldfs); |
951 | if (host_err >= 0) { | 951 | if (host_err >= 0) { |
952 | nfsdstats.io_write += cnt; | 952 | nfsdstats.io_write += cnt; |
953 | fsnotify_modify(file->f_dentry); | 953 | fsnotify_modify(file->f_path.dentry); |
954 | } | 954 | } |
955 | 955 | ||
956 | /* clear setuid/setgid flag after write */ | 956 | /* clear setuid/setgid flag after write */ |
@@ -1885,28 +1885,27 @@ nfsd_racache_init(int cache_size) | |||
1885 | return 0; | 1885 | return 0; |
1886 | if (cache_size < 2*RAPARM_HASH_SIZE) | 1886 | if (cache_size < 2*RAPARM_HASH_SIZE) |
1887 | cache_size = 2*RAPARM_HASH_SIZE; | 1887 | cache_size = 2*RAPARM_HASH_SIZE; |
1888 | raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL); | 1888 | raparml = kcalloc(cache_size, sizeof(struct raparms), GFP_KERNEL); |
1889 | 1889 | ||
1890 | if (raparml != NULL) { | 1890 | if (!raparml) { |
1891 | dprintk("nfsd: allocating %d readahead buffers.\n", | ||
1892 | cache_size); | ||
1893 | for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) { | ||
1894 | raparm_hash[i].pb_head = NULL; | ||
1895 | spin_lock_init(&raparm_hash[i].pb_lock); | ||
1896 | } | ||
1897 | nperbucket = cache_size >> RAPARM_HASH_BITS; | ||
1898 | memset(raparml, 0, sizeof(struct raparms) * cache_size); | ||
1899 | for (i = 0; i < cache_size - 1; i++) { | ||
1900 | if (i % nperbucket == 0) | ||
1901 | raparm_hash[j++].pb_head = raparml + i; | ||
1902 | if (i % nperbucket < nperbucket-1) | ||
1903 | raparml[i].p_next = raparml + i + 1; | ||
1904 | } | ||
1905 | } else { | ||
1906 | printk(KERN_WARNING | 1891 | printk(KERN_WARNING |
1907 | "nfsd: Could not allocate memory read-ahead cache.\n"); | 1892 | "nfsd: Could not allocate memory read-ahead cache.\n"); |
1908 | return -ENOMEM; | 1893 | return -ENOMEM; |
1909 | } | 1894 | } |
1895 | |||
1896 | dprintk("nfsd: allocating %d readahead buffers.\n", cache_size); | ||
1897 | for (i = 0 ; i < RAPARM_HASH_SIZE ; i++) { | ||
1898 | raparm_hash[i].pb_head = NULL; | ||
1899 | spin_lock_init(&raparm_hash[i].pb_lock); | ||
1900 | } | ||
1901 | nperbucket = cache_size >> RAPARM_HASH_BITS; | ||
1902 | for (i = 0; i < cache_size - 1; i++) { | ||
1903 | if (i % nperbucket == 0) | ||
1904 | raparm_hash[j++].pb_head = raparml + i; | ||
1905 | if (i % nperbucket < nperbucket-1) | ||
1906 | raparml[i].p_next = raparml + i + 1; | ||
1907 | } | ||
1908 | |||
1910 | nfsdstats.ra_size = cache_size; | 1909 | nfsdstats.ra_size = cache_size; |
1911 | return 0; | 1910 | return 0; |
1912 | } | 1911 | } |
diff --git a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c index 046fde8170ea..65e640c61c8b 100644 --- a/fs/nls/nls_cp936.c +++ b/fs/nls/nls_cp936.c | |||
@@ -4421,6 +4421,73 @@ static wchar_t *page_charset2uni[256] = { | |||
4421 | c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL, | 4421 | c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL, |
4422 | }; | 4422 | }; |
4423 | 4423 | ||
4424 | static unsigned char u2c_00[512] = { | ||
4425 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ | ||
4426 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ | ||
4427 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */ | ||
4428 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C-0x0F */ | ||
4429 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */ | ||
4430 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x14-0x17 */ | ||
4431 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1B */ | ||
4432 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1C-0x1F */ | ||
4433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x23 */ | ||
4434 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x24-0x27 */ | ||
4435 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */ | ||
4436 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */ | ||
4437 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x33 */ | ||
4438 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x34-0x37 */ | ||
4439 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3B */ | ||
4440 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3C-0x3F */ | ||
4441 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x43 */ | ||
4442 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x44-0x47 */ | ||
4443 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4B */ | ||
4444 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */ | ||
4445 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */ | ||
4446 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x54-0x57 */ | ||
4447 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5B */ | ||
4448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5C-0x5F */ | ||
4449 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x63 */ | ||
4450 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x64-0x67 */ | ||
4451 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6B */ | ||
4452 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */ | ||
4453 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */ | ||
4454 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x74-0x77 */ | ||
4455 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7B */ | ||
4456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7C-0x7F */ | ||
4457 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */ | ||
4458 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x84-0x87 */ | ||
4459 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8B */ | ||
4460 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8C-0x8F */ | ||
4461 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x93 */ | ||
4462 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x94-0x97 */ | ||
4463 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */ | ||
4464 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */ | ||
4465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA0-0xA3 */ | ||
4466 | 0xA1, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xEC, /* 0xA4-0xA7 */ | ||
4467 | 0xA1, 0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */ | ||
4468 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xAC-0xAF */ | ||
4469 | 0xA1, 0xE3, 0xA1, 0xC0, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */ | ||
4470 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA4, /* 0xB4-0xB7 */ | ||
4471 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB8-0xBB */ | ||
4472 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xBC-0xBF */ | ||
4473 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC0-0xC3 */ | ||
4474 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC4-0xC7 */ | ||
4475 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */ | ||
4476 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xCC-0xCF */ | ||
4477 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD0-0xD3 */ | ||
4478 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC1, /* 0xD4-0xD7 */ | ||
4479 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */ | ||
4480 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */ | ||
4481 | 0xA8, 0xA4, 0xA8, 0xA2, 0x00, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */ | ||
4482 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */ | ||
4483 | 0xA8, 0xA8, 0xA8, 0xA6, 0xA8, 0xBA, 0x00, 0x00, /* 0xE8-0xEB */ | ||
4484 | 0xA8, 0xAC, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0xEC-0xEF */ | ||
4485 | 0x00, 0x00, 0x00, 0x00, 0xA8, 0xB0, 0xA8, 0xAE, /* 0xF0-0xF3 */ | ||
4486 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC2, /* 0xF4-0xF7 */ | ||
4487 | 0x00, 0x00, 0xA8, 0xB4, 0xA8, 0xB2, 0x00, 0x00, /* 0xF8-0xFB */ | ||
4488 | 0xA8, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */ | ||
4489 | }; | ||
4490 | |||
4424 | static unsigned char u2c_01[512] = { | 4491 | static unsigned char u2c_01[512] = { |
4425 | 0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ | 4492 | 0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ |
4426 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ | 4493 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ |
@@ -10825,7 +10892,7 @@ static unsigned char u2c_FF[512] = { | |||
10825 | }; | 10892 | }; |
10826 | 10893 | ||
10827 | static unsigned char *page_uni2charset[256] = { | 10894 | static unsigned char *page_uni2charset[256] = { |
10828 | NULL, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, | 10895 | u2c_00, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, |
10829 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10896 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
10830 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10897 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
10831 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10898 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
@@ -10936,11 +11003,34 @@ static int uni2char(const wchar_t uni, | |||
10936 | unsigned char *uni2charset; | 11003 | unsigned char *uni2charset; |
10937 | unsigned char cl = uni&0xFF; | 11004 | unsigned char cl = uni&0xFF; |
10938 | unsigned char ch = (uni>>8)&0xFF; | 11005 | unsigned char ch = (uni>>8)&0xFF; |
10939 | int n; | 11006 | unsigned char out0,out1; |
10940 | 11007 | ||
10941 | if (boundlen <= 0) | 11008 | if (boundlen <= 0) |
10942 | return -ENAMETOOLONG; | 11009 | return -ENAMETOOLONG; |
10943 | 11010 | ||
11011 | if (uni == 0x20ac) {/* Euro symbol.The only exception with a non-ascii unicode */ | ||
11012 | out[0] = 0x80; | ||
11013 | return 1; | ||
11014 | } | ||
11015 | |||
11016 | if (ch == 0) { /* handle the U00 plane*/ | ||
11017 | /* if (cl == 0) return -EINVAL;*/ /*U0000 is legal in cp936*/ | ||
11018 | out0 = u2c_00[cl*2]; | ||
11019 | out1 = u2c_00[cl*2+1]; | ||
11020 | if (out0 == 0x00 && out1 == 0x00) { | ||
11021 | if (cl<0x80) { | ||
11022 | out[0] = cl; | ||
11023 | return 1; | ||
11024 | } | ||
11025 | return -EINVAL; | ||
11026 | } else { | ||
11027 | if (boundlen <= 1) | ||
11028 | return -ENAMETOOLONG; | ||
11029 | out[0] = out0; | ||
11030 | out[1] = out1; | ||
11031 | return 2; | ||
11032 | } | ||
11033 | } | ||
10944 | 11034 | ||
10945 | uni2charset = page_uni2charset[ch]; | 11035 | uni2charset = page_uni2charset[ch]; |
10946 | if (uni2charset) { | 11036 | if (uni2charset) { |
@@ -10950,15 +11040,10 @@ static int uni2char(const wchar_t uni, | |||
10950 | out[1] = uni2charset[cl*2+1]; | 11040 | out[1] = uni2charset[cl*2+1]; |
10951 | if (out[0] == 0x00 && out[1] == 0x00) | 11041 | if (out[0] == 0x00 && out[1] == 0x00) |
10952 | return -EINVAL; | 11042 | return -EINVAL; |
10953 | n = 2; | 11043 | return 2; |
10954 | } else if (ch==0 && cl) { | ||
10955 | out[0] = cl; | ||
10956 | n = 1; | ||
10957 | } | 11044 | } |
10958 | else | 11045 | else |
10959 | return -EINVAL; | 11046 | return -EINVAL; |
10960 | |||
10961 | return n; | ||
10962 | } | 11047 | } |
10963 | 11048 | ||
10964 | static int char2uni(const unsigned char *rawstring, int boundlen, | 11049 | static int char2uni(const unsigned char *rawstring, int boundlen, |
@@ -10972,7 +11057,11 @@ static int char2uni(const unsigned char *rawstring, int boundlen, | |||
10972 | return -ENAMETOOLONG; | 11057 | return -ENAMETOOLONG; |
10973 | 11058 | ||
10974 | if (boundlen == 1) { | 11059 | if (boundlen == 1) { |
10975 | *uni = rawstring[0]; | 11060 | if (rawstring[0]==0x80) { /* Euro symbol.The only exception with a non-ascii unicode */ |
11061 | *uni = 0x20ac; | ||
11062 | } else { | ||
11063 | *uni = rawstring[0]; | ||
11064 | } | ||
10976 | return 1; | 11065 | return 1; |
10977 | } | 11066 | } |
10978 | 11067 | ||
@@ -10986,7 +11075,11 @@ static int char2uni(const unsigned char *rawstring, int boundlen, | |||
10986 | return -EINVAL; | 11075 | return -EINVAL; |
10987 | n = 2; | 11076 | n = 2; |
10988 | } else{ | 11077 | } else{ |
10989 | *uni = ch; | 11078 | if (ch==0x80) {/* Euro symbol.The only exception with a non-ascii unicode */ |
11079 | *uni = 0x20ac; | ||
11080 | } else { | ||
11081 | *uni = ch; | ||
11082 | } | ||
10990 | n = 1; | 11083 | n = 1; |
10991 | } | 11084 | } |
10992 | return n; | 11085 | return n; |
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 9f08e851cfb6..c577d8e1bd95 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
@@ -1272,7 +1272,7 @@ ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) | |||
1272 | { | 1272 | { |
1273 | ntfs_attr_search_ctx *ctx; | 1273 | ntfs_attr_search_ctx *ctx; |
1274 | 1274 | ||
1275 | ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS); | 1275 | ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, GFP_NOFS); |
1276 | if (ctx) | 1276 | if (ctx) |
1277 | ntfs_attr_init_search_ctx(ctx, ni, mrec); | 1277 | ntfs_attr_init_search_ctx(ctx, ni, mrec); |
1278 | return ctx; | 1278 | return ctx; |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 85c36b8ca452..8296c29ae3b8 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
@@ -1101,7 +1101,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1101 | { | 1101 | { |
1102 | s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; | 1102 | s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; |
1103 | loff_t fpos, i_size; | 1103 | loff_t fpos, i_size; |
1104 | struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode; | 1104 | struct inode *bmp_vi, *vdir = filp->f_path.dentry->d_inode; |
1105 | struct super_block *sb = vdir->i_sb; | 1105 | struct super_block *sb = vdir->i_sb; |
1106 | ntfs_inode *ndir = NTFS_I(vdir); | 1106 | ntfs_inode *ndir = NTFS_I(vdir); |
1107 | ntfs_volume *vol = NTFS_SB(sb); | 1107 | ntfs_volume *vol = NTFS_SB(sb); |
@@ -1136,9 +1136,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1136 | if (fpos == 1) { | 1136 | if (fpos == 1) { |
1137 | ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, " | 1137 | ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, " |
1138 | "inode 0x%lx, DT_DIR.", | 1138 | "inode 0x%lx, DT_DIR.", |
1139 | (unsigned long)parent_ino(filp->f_dentry)); | 1139 | (unsigned long)parent_ino(filp->f_path.dentry)); |
1140 | rc = filldir(dirent, "..", 2, fpos, | 1140 | rc = filldir(dirent, "..", 2, fpos, |
1141 | parent_ino(filp->f_dentry), DT_DIR); | 1141 | parent_ino(filp->f_path.dentry), DT_DIR); |
1142 | if (rc) | 1142 | if (rc) |
1143 | goto done; | 1143 | goto done; |
1144 | fpos++; | 1144 | fpos++; |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index ae2fe0016d2c..076c9420c257 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -2162,7 +2162,7 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, | |||
2162 | goto out; | 2162 | goto out; |
2163 | if (!count) | 2163 | if (!count) |
2164 | goto out; | 2164 | goto out; |
2165 | err = remove_suid(file->f_dentry); | 2165 | err = remove_suid(file->f_path.dentry); |
2166 | if (err) | 2166 | if (err) |
2167 | goto out; | 2167 | goto out; |
2168 | file_update_time(file); | 2168 | file_update_time(file); |
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index e32cde486362..2194eff49743 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c | |||
@@ -38,7 +38,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) | |||
38 | { | 38 | { |
39 | ntfs_index_context *ictx; | 39 | ntfs_index_context *ictx; |
40 | 40 | ||
41 | ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS); | 41 | ictx = kmem_cache_alloc(ntfs_index_ctx_cache, GFP_NOFS); |
42 | if (ictx) | 42 | if (ictx) |
43 | *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; | 43 | *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; |
44 | return ictx; | 44 | return ictx; |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 2d3de9c89818..247989891b4b 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -324,7 +324,7 @@ struct inode *ntfs_alloc_big_inode(struct super_block *sb) | |||
324 | ntfs_inode *ni; | 324 | ntfs_inode *ni; |
325 | 325 | ||
326 | ntfs_debug("Entering."); | 326 | ntfs_debug("Entering."); |
327 | ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS); | 327 | ni = kmem_cache_alloc(ntfs_big_inode_cache, GFP_NOFS); |
328 | if (likely(ni != NULL)) { | 328 | if (likely(ni != NULL)) { |
329 | ni->state = 0; | 329 | ni->state = 0; |
330 | return VFS_I(ni); | 330 | return VFS_I(ni); |
@@ -349,7 +349,7 @@ static inline ntfs_inode *ntfs_alloc_extent_inode(void) | |||
349 | ntfs_inode *ni; | 349 | ntfs_inode *ni; |
350 | 350 | ||
351 | ntfs_debug("Entering."); | 351 | ntfs_debug("Entering."); |
352 | ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS); | 352 | ni = kmem_cache_alloc(ntfs_inode_cache, GFP_NOFS); |
353 | if (likely(ni != NULL)) { | 353 | if (likely(ni != NULL)) { |
354 | ni->state = 0; | 354 | ni->state = 0; |
355 | return ni; | 355 | return ni; |
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index 6a495f7369f9..005ca4b0f132 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c | |||
@@ -266,7 +266,7 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins, | |||
266 | 266 | ||
267 | /* We do not trust outside sources. */ | 267 | /* We do not trust outside sources. */ |
268 | if (likely(ins)) { | 268 | if (likely(ins)) { |
269 | ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); | 269 | ucs = kmem_cache_alloc(ntfs_name_cache, GFP_NOFS); |
270 | if (likely(ucs)) { | 270 | if (likely(ucs)) { |
271 | for (i = o = 0; i < ins_len; i += wc_len) { | 271 | for (i = o = 0; i < ins_len; i += wc_len) { |
272 | wc_len = nls->char2uni(ins + i, ins_len - i, | 272 | wc_len = nls->char2uni(ins + i, ins_len - i, |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index f43bc5f18a35..f27e5378caf2 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -52,14 +52,14 @@ static int ocfs2_extent_contig(struct inode *inode, | |||
52 | u64 blkno); | 52 | u64 blkno); |
53 | 53 | ||
54 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, | 54 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, |
55 | struct ocfs2_journal_handle *handle, | 55 | handle_t *handle, |
56 | struct inode *inode, | 56 | struct inode *inode, |
57 | int wanted, | 57 | int wanted, |
58 | struct ocfs2_alloc_context *meta_ac, | 58 | struct ocfs2_alloc_context *meta_ac, |
59 | struct buffer_head *bhs[]); | 59 | struct buffer_head *bhs[]); |
60 | 60 | ||
61 | static int ocfs2_add_branch(struct ocfs2_super *osb, | 61 | static int ocfs2_add_branch(struct ocfs2_super *osb, |
62 | struct ocfs2_journal_handle *handle, | 62 | handle_t *handle, |
63 | struct inode *inode, | 63 | struct inode *inode, |
64 | struct buffer_head *fe_bh, | 64 | struct buffer_head *fe_bh, |
65 | struct buffer_head *eb_bh, | 65 | struct buffer_head *eb_bh, |
@@ -67,14 +67,14 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
67 | struct ocfs2_alloc_context *meta_ac); | 67 | struct ocfs2_alloc_context *meta_ac); |
68 | 68 | ||
69 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | 69 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, |
70 | struct ocfs2_journal_handle *handle, | 70 | handle_t *handle, |
71 | struct inode *inode, | 71 | struct inode *inode, |
72 | struct buffer_head *fe_bh, | 72 | struct buffer_head *fe_bh, |
73 | struct ocfs2_alloc_context *meta_ac, | 73 | struct ocfs2_alloc_context *meta_ac, |
74 | struct buffer_head **ret_new_eb_bh); | 74 | struct buffer_head **ret_new_eb_bh); |
75 | 75 | ||
76 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, | 76 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, |
77 | struct ocfs2_journal_handle *handle, | 77 | handle_t *handle, |
78 | struct inode *inode, | 78 | struct inode *inode, |
79 | struct buffer_head *fe_bh, | 79 | struct buffer_head *fe_bh, |
80 | u64 blkno, | 80 | u64 blkno, |
@@ -152,7 +152,7 @@ bail: | |||
152 | * l_count for you | 152 | * l_count for you |
153 | */ | 153 | */ |
154 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, | 154 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, |
155 | struct ocfs2_journal_handle *handle, | 155 | handle_t *handle, |
156 | struct inode *inode, | 156 | struct inode *inode, |
157 | int wanted, | 157 | int wanted, |
158 | struct ocfs2_alloc_context *meta_ac, | 158 | struct ocfs2_alloc_context *meta_ac, |
@@ -253,7 +253,7 @@ bail: | |||
253 | * contain a single record with e_clusters == 0. | 253 | * contain a single record with e_clusters == 0. |
254 | */ | 254 | */ |
255 | static int ocfs2_add_branch(struct ocfs2_super *osb, | 255 | static int ocfs2_add_branch(struct ocfs2_super *osb, |
256 | struct ocfs2_journal_handle *handle, | 256 | handle_t *handle, |
257 | struct inode *inode, | 257 | struct inode *inode, |
258 | struct buffer_head *fe_bh, | 258 | struct buffer_head *fe_bh, |
259 | struct buffer_head *eb_bh, | 259 | struct buffer_head *eb_bh, |
@@ -418,7 +418,7 @@ bail: | |||
418 | * after this call. | 418 | * after this call. |
419 | */ | 419 | */ |
420 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | 420 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, |
421 | struct ocfs2_journal_handle *handle, | 421 | handle_t *handle, |
422 | struct inode *inode, | 422 | struct inode *inode, |
423 | struct buffer_head *fe_bh, | 423 | struct buffer_head *fe_bh, |
424 | struct ocfs2_alloc_context *meta_ac, | 424 | struct ocfs2_alloc_context *meta_ac, |
@@ -520,7 +520,7 @@ bail: | |||
520 | * down. | 520 | * down. |
521 | */ | 521 | */ |
522 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, | 522 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, |
523 | struct ocfs2_journal_handle *handle, | 523 | handle_t *handle, |
524 | struct inode *inode, | 524 | struct inode *inode, |
525 | struct buffer_head *fe_bh, | 525 | struct buffer_head *fe_bh, |
526 | u64 start_blk, | 526 | u64 start_blk, |
@@ -809,7 +809,7 @@ bail: | |||
809 | 809 | ||
810 | /* the caller needs to update fe->i_clusters */ | 810 | /* the caller needs to update fe->i_clusters */ |
811 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 811 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
812 | struct ocfs2_journal_handle *handle, | 812 | handle_t *handle, |
813 | struct inode *inode, | 813 | struct inode *inode, |
814 | struct buffer_head *fe_bh, | 814 | struct buffer_head *fe_bh, |
815 | u64 start_blk, | 815 | u64 start_blk, |
@@ -951,7 +951,7 @@ static int ocfs2_truncate_log_can_coalesce(struct ocfs2_truncate_log *tl, | |||
951 | } | 951 | } |
952 | 952 | ||
953 | static int ocfs2_truncate_log_append(struct ocfs2_super *osb, | 953 | static int ocfs2_truncate_log_append(struct ocfs2_super *osb, |
954 | struct ocfs2_journal_handle *handle, | 954 | handle_t *handle, |
955 | u64 start_blk, | 955 | u64 start_blk, |
956 | unsigned int num_clusters) | 956 | unsigned int num_clusters) |
957 | { | 957 | { |
@@ -1034,7 +1034,7 @@ bail: | |||
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, | 1036 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, |
1037 | struct ocfs2_journal_handle *handle, | 1037 | handle_t *handle, |
1038 | struct inode *data_alloc_inode, | 1038 | struct inode *data_alloc_inode, |
1039 | struct buffer_head *data_alloc_bh) | 1039 | struct buffer_head *data_alloc_bh) |
1040 | { | 1040 | { |
@@ -1113,7 +1113,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1113 | { | 1113 | { |
1114 | int status; | 1114 | int status; |
1115 | unsigned int num_to_flush; | 1115 | unsigned int num_to_flush; |
1116 | struct ocfs2_journal_handle *handle = NULL; | 1116 | handle_t *handle; |
1117 | struct inode *tl_inode = osb->osb_tl_inode; | 1117 | struct inode *tl_inode = osb->osb_tl_inode; |
1118 | struct inode *data_alloc_inode = NULL; | 1118 | struct inode *data_alloc_inode = NULL; |
1119 | struct buffer_head *tl_bh = osb->osb_tl_bh; | 1119 | struct buffer_head *tl_bh = osb->osb_tl_bh; |
@@ -1130,7 +1130,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1130 | if (!OCFS2_IS_VALID_DINODE(di)) { | 1130 | if (!OCFS2_IS_VALID_DINODE(di)) { |
1131 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); | 1131 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); |
1132 | status = -EIO; | 1132 | status = -EIO; |
1133 | goto bail; | 1133 | goto out; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | num_to_flush = le16_to_cpu(tl->tl_used); | 1136 | num_to_flush = le16_to_cpu(tl->tl_used); |
@@ -1138,14 +1138,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1138 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); | 1138 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); |
1139 | if (!num_to_flush) { | 1139 | if (!num_to_flush) { |
1140 | status = 0; | 1140 | status = 0; |
1141 | goto bail; | 1141 | goto out; |
1142 | } | ||
1143 | |||
1144 | handle = ocfs2_alloc_handle(osb); | ||
1145 | if (!handle) { | ||
1146 | status = -ENOMEM; | ||
1147 | mlog_errno(status); | ||
1148 | goto bail; | ||
1149 | } | 1142 | } |
1150 | 1143 | ||
1151 | data_alloc_inode = ocfs2_get_system_file_inode(osb, | 1144 | data_alloc_inode = ocfs2_get_system_file_inode(osb, |
@@ -1154,41 +1147,40 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1154 | if (!data_alloc_inode) { | 1147 | if (!data_alloc_inode) { |
1155 | status = -EINVAL; | 1148 | status = -EINVAL; |
1156 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); | 1149 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); |
1157 | goto bail; | 1150 | goto out; |
1158 | } | 1151 | } |
1159 | 1152 | ||
1160 | ocfs2_handle_add_inode(handle, data_alloc_inode); | 1153 | mutex_lock(&data_alloc_inode->i_mutex); |
1161 | status = ocfs2_meta_lock(data_alloc_inode, handle, &data_alloc_bh, 1); | 1154 | |
1155 | status = ocfs2_meta_lock(data_alloc_inode, &data_alloc_bh, 1); | ||
1162 | if (status < 0) { | 1156 | if (status < 0) { |
1163 | mlog_errno(status); | 1157 | mlog_errno(status); |
1164 | goto bail; | 1158 | goto out_mutex; |
1165 | } | 1159 | } |
1166 | 1160 | ||
1167 | handle = ocfs2_start_trans(osb, handle, OCFS2_TRUNCATE_LOG_UPDATE); | 1161 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE); |
1168 | if (IS_ERR(handle)) { | 1162 | if (IS_ERR(handle)) { |
1169 | status = PTR_ERR(handle); | 1163 | status = PTR_ERR(handle); |
1170 | handle = NULL; | ||
1171 | mlog_errno(status); | 1164 | mlog_errno(status); |
1172 | goto bail; | 1165 | goto out_unlock; |
1173 | } | 1166 | } |
1174 | 1167 | ||
1175 | status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, | 1168 | status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, |
1176 | data_alloc_bh); | 1169 | data_alloc_bh); |
1177 | if (status < 0) { | 1170 | if (status < 0) |
1178 | mlog_errno(status); | 1171 | mlog_errno(status); |
1179 | goto bail; | ||
1180 | } | ||
1181 | 1172 | ||
1182 | bail: | 1173 | ocfs2_commit_trans(osb, handle); |
1183 | if (handle) | ||
1184 | ocfs2_commit_trans(handle); | ||
1185 | 1174 | ||
1186 | if (data_alloc_inode) | 1175 | out_unlock: |
1187 | iput(data_alloc_inode); | 1176 | brelse(data_alloc_bh); |
1177 | ocfs2_meta_unlock(data_alloc_inode, 1); | ||
1188 | 1178 | ||
1189 | if (data_alloc_bh) | 1179 | out_mutex: |
1190 | brelse(data_alloc_bh); | 1180 | mutex_unlock(&data_alloc_inode->i_mutex); |
1181 | iput(data_alloc_inode); | ||
1191 | 1182 | ||
1183 | out: | ||
1192 | mlog_exit(status); | 1184 | mlog_exit(status); |
1193 | return status; | 1185 | return status; |
1194 | } | 1186 | } |
@@ -1205,10 +1197,12 @@ int ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1205 | return status; | 1197 | return status; |
1206 | } | 1198 | } |
1207 | 1199 | ||
1208 | static void ocfs2_truncate_log_worker(void *data) | 1200 | static void ocfs2_truncate_log_worker(struct work_struct *work) |
1209 | { | 1201 | { |
1210 | int status; | 1202 | int status; |
1211 | struct ocfs2_super *osb = data; | 1203 | struct ocfs2_super *osb = |
1204 | container_of(work, struct ocfs2_super, | ||
1205 | osb_truncate_log_wq.work); | ||
1212 | 1206 | ||
1213 | mlog_entry_void(); | 1207 | mlog_entry_void(); |
1214 | 1208 | ||
@@ -1347,7 +1341,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1347 | int i; | 1341 | int i; |
1348 | unsigned int clusters, num_recs, start_cluster; | 1342 | unsigned int clusters, num_recs, start_cluster; |
1349 | u64 start_blk; | 1343 | u64 start_blk; |
1350 | struct ocfs2_journal_handle *handle; | 1344 | handle_t *handle; |
1351 | struct inode *tl_inode = osb->osb_tl_inode; | 1345 | struct inode *tl_inode = osb->osb_tl_inode; |
1352 | struct ocfs2_truncate_log *tl; | 1346 | struct ocfs2_truncate_log *tl; |
1353 | 1347 | ||
@@ -1373,8 +1367,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1373 | } | 1367 | } |
1374 | } | 1368 | } |
1375 | 1369 | ||
1376 | handle = ocfs2_start_trans(osb, NULL, | 1370 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE); |
1377 | OCFS2_TRUNCATE_LOG_UPDATE); | ||
1378 | if (IS_ERR(handle)) { | 1371 | if (IS_ERR(handle)) { |
1379 | status = PTR_ERR(handle); | 1372 | status = PTR_ERR(handle); |
1380 | mlog_errno(status); | 1373 | mlog_errno(status); |
@@ -1387,7 +1380,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1387 | 1380 | ||
1388 | status = ocfs2_truncate_log_append(osb, handle, | 1381 | status = ocfs2_truncate_log_append(osb, handle, |
1389 | start_blk, clusters); | 1382 | start_blk, clusters); |
1390 | ocfs2_commit_trans(handle); | 1383 | ocfs2_commit_trans(osb, handle); |
1391 | if (status < 0) { | 1384 | if (status < 0) { |
1392 | mlog_errno(status); | 1385 | mlog_errno(status); |
1393 | goto bail_up; | 1386 | goto bail_up; |
@@ -1441,7 +1434,8 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb) | |||
1441 | /* ocfs2_truncate_log_shutdown keys on the existence of | 1434 | /* ocfs2_truncate_log_shutdown keys on the existence of |
1442 | * osb->osb_tl_inode so we don't set any of the osb variables | 1435 | * osb->osb_tl_inode so we don't set any of the osb variables |
1443 | * until we're sure all is well. */ | 1436 | * until we're sure all is well. */ |
1444 | INIT_WORK(&osb->osb_truncate_log_wq, ocfs2_truncate_log_worker, osb); | 1437 | INIT_DELAYED_WORK(&osb->osb_truncate_log_wq, |
1438 | ocfs2_truncate_log_worker); | ||
1445 | osb->osb_tl_bh = tl_bh; | 1439 | osb->osb_tl_bh = tl_bh; |
1446 | osb->osb_tl_inode = tl_inode; | 1440 | osb->osb_tl_inode = tl_inode; |
1447 | 1441 | ||
@@ -1543,7 +1537,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb, | |||
1543 | struct inode *inode, | 1537 | struct inode *inode, |
1544 | struct buffer_head *fe_bh, | 1538 | struct buffer_head *fe_bh, |
1545 | struct buffer_head *old_last_eb_bh, | 1539 | struct buffer_head *old_last_eb_bh, |
1546 | struct ocfs2_journal_handle *handle, | 1540 | handle_t *handle, |
1547 | struct ocfs2_truncate_context *tc) | 1541 | struct ocfs2_truncate_context *tc) |
1548 | { | 1542 | { |
1549 | int status, i, depth; | 1543 | int status, i, depth; |
@@ -1782,7 +1776,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, | |||
1782 | struct ocfs2_extent_block *eb; | 1776 | struct ocfs2_extent_block *eb; |
1783 | struct ocfs2_extent_list *el; | 1777 | struct ocfs2_extent_list *el; |
1784 | struct buffer_head *last_eb_bh; | 1778 | struct buffer_head *last_eb_bh; |
1785 | struct ocfs2_journal_handle *handle = NULL; | 1779 | handle_t *handle = NULL; |
1786 | struct inode *tl_inode = osb->osb_tl_inode; | 1780 | struct inode *tl_inode = osb->osb_tl_inode; |
1787 | 1781 | ||
1788 | mlog_entry_void(); | 1782 | mlog_entry_void(); |
@@ -1868,7 +1862,7 @@ start: | |||
1868 | 1862 | ||
1869 | credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, | 1863 | credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, |
1870 | fe, el); | 1864 | fe, el); |
1871 | handle = ocfs2_start_trans(osb, NULL, credits); | 1865 | handle = ocfs2_start_trans(osb, credits); |
1872 | if (IS_ERR(handle)) { | 1866 | if (IS_ERR(handle)) { |
1873 | status = PTR_ERR(handle); | 1867 | status = PTR_ERR(handle); |
1874 | handle = NULL; | 1868 | handle = NULL; |
@@ -1891,7 +1885,7 @@ start: | |||
1891 | mutex_unlock(&tl_inode->i_mutex); | 1885 | mutex_unlock(&tl_inode->i_mutex); |
1892 | tl_sem = 0; | 1886 | tl_sem = 0; |
1893 | 1887 | ||
1894 | ocfs2_commit_trans(handle); | 1888 | ocfs2_commit_trans(osb, handle); |
1895 | handle = NULL; | 1889 | handle = NULL; |
1896 | 1890 | ||
1897 | BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters); | 1891 | BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters); |
@@ -1906,7 +1900,7 @@ bail: | |||
1906 | mutex_unlock(&tl_inode->i_mutex); | 1900 | mutex_unlock(&tl_inode->i_mutex); |
1907 | 1901 | ||
1908 | if (handle) | 1902 | if (handle) |
1909 | ocfs2_commit_trans(handle); | 1903 | ocfs2_commit_trans(osb, handle); |
1910 | 1904 | ||
1911 | if (last_eb_bh) | 1905 | if (last_eb_bh) |
1912 | brelse(last_eb_bh); | 1906 | brelse(last_eb_bh); |
@@ -1965,7 +1959,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
1965 | goto bail; | 1959 | goto bail; |
1966 | } | 1960 | } |
1967 | 1961 | ||
1968 | *tc = kcalloc(1, sizeof(struct ocfs2_truncate_context), GFP_KERNEL); | 1962 | *tc = kzalloc(sizeof(struct ocfs2_truncate_context), GFP_KERNEL); |
1969 | if (!(*tc)) { | 1963 | if (!(*tc)) { |
1970 | status = -ENOMEM; | 1964 | status = -ENOMEM; |
1971 | mlog_errno(status); | 1965 | mlog_errno(status); |
@@ -2011,10 +2005,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
2011 | mutex_lock(&ext_alloc_inode->i_mutex); | 2005 | mutex_lock(&ext_alloc_inode->i_mutex); |
2012 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; | 2006 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; |
2013 | 2007 | ||
2014 | status = ocfs2_meta_lock(ext_alloc_inode, | 2008 | status = ocfs2_meta_lock(ext_alloc_inode, &ext_alloc_bh, 1); |
2015 | NULL, | ||
2016 | &ext_alloc_bh, | ||
2017 | 1); | ||
2018 | if (status < 0) { | 2009 | if (status < 0) { |
2019 | mlog_errno(status); | 2010 | mlog_errno(status); |
2020 | goto bail; | 2011 | goto bail; |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 12ba897743f4..0b82e8044325 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | struct ocfs2_alloc_context; | 29 | struct ocfs2_alloc_context; |
30 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 30 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
31 | struct ocfs2_journal_handle *handle, | 31 | handle_t *handle, |
32 | struct inode *inode, | 32 | struct inode *inode, |
33 | struct buffer_head *fe_bh, | 33 | struct buffer_head *fe_bh, |
34 | u64 blkno, | 34 | u64 blkno, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 3d7c082a8f58..93628b02ef5d 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -200,7 +200,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) | |||
200 | 200 | ||
201 | mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); | 201 | mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); |
202 | 202 | ||
203 | ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); | 203 | ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page); |
204 | if (ret != 0) { | 204 | if (ret != 0) { |
205 | if (ret == AOP_TRUNCATED_PAGE) | 205 | if (ret == AOP_TRUNCATED_PAGE) |
206 | unlock = 0; | 206 | unlock = 0; |
@@ -305,7 +305,7 @@ static int ocfs2_prepare_write(struct file *file, struct page *page, | |||
305 | 305 | ||
306 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); | 306 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); |
307 | 307 | ||
308 | ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); | 308 | ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page); |
309 | if (ret != 0) { | 309 | if (ret != 0) { |
310 | mlog_errno(ret); | 310 | mlog_errno(ret); |
311 | goto out; | 311 | goto out; |
@@ -355,16 +355,16 @@ static int walk_page_buffers( handle_t *handle, | |||
355 | return ret; | 355 | return ret; |
356 | } | 356 | } |
357 | 357 | ||
358 | struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | 358 | handle_t *ocfs2_start_walk_page_trans(struct inode *inode, |
359 | struct page *page, | 359 | struct page *page, |
360 | unsigned from, | 360 | unsigned from, |
361 | unsigned to) | 361 | unsigned to) |
362 | { | 362 | { |
363 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 363 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
364 | struct ocfs2_journal_handle *handle = NULL; | 364 | handle_t *handle = NULL; |
365 | int ret = 0; | 365 | int ret = 0; |
366 | 366 | ||
367 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 367 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
368 | if (!handle) { | 368 | if (!handle) { |
369 | ret = -ENOMEM; | 369 | ret = -ENOMEM; |
370 | mlog_errno(ret); | 370 | mlog_errno(ret); |
@@ -372,7 +372,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | if (ocfs2_should_order_data(inode)) { | 374 | if (ocfs2_should_order_data(inode)) { |
375 | ret = walk_page_buffers(handle->k_handle, | 375 | ret = walk_page_buffers(handle, |
376 | page_buffers(page), | 376 | page_buffers(page), |
377 | from, to, NULL, | 377 | from, to, NULL, |
378 | ocfs2_journal_dirty_data); | 378 | ocfs2_journal_dirty_data); |
@@ -382,7 +382,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | |||
382 | out: | 382 | out: |
383 | if (ret) { | 383 | if (ret) { |
384 | if (handle) | 384 | if (handle) |
385 | ocfs2_commit_trans(handle); | 385 | ocfs2_commit_trans(osb, handle); |
386 | handle = ERR_PTR(ret); | 386 | handle = ERR_PTR(ret); |
387 | } | 387 | } |
388 | return handle; | 388 | return handle; |
@@ -394,7 +394,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
394 | int ret; | 394 | int ret; |
395 | struct buffer_head *di_bh = NULL; | 395 | struct buffer_head *di_bh = NULL; |
396 | struct inode *inode = page->mapping->host; | 396 | struct inode *inode = page->mapping->host; |
397 | struct ocfs2_journal_handle *handle = NULL; | 397 | handle_t *handle = NULL; |
398 | struct ocfs2_dinode *di; | 398 | struct ocfs2_dinode *di; |
399 | 399 | ||
400 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); | 400 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); |
@@ -412,7 +412,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
412 | * stale inode allocation image (i_size, i_clusters, etc). | 412 | * stale inode allocation image (i_size, i_clusters, etc). |
413 | */ | 413 | */ |
414 | 414 | ||
415 | ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, 1, page); | 415 | ret = ocfs2_meta_lock_with_page(inode, &di_bh, 1, page); |
416 | if (ret != 0) { | 416 | if (ret != 0) { |
417 | mlog_errno(ret); | 417 | mlog_errno(ret); |
418 | goto out; | 418 | goto out; |
@@ -464,7 +464,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
464 | } | 464 | } |
465 | 465 | ||
466 | out_commit: | 466 | out_commit: |
467 | ocfs2_commit_trans(handle); | 467 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
468 | out_unlock_data: | 468 | out_unlock_data: |
469 | ocfs2_data_unlock(inode, 1); | 469 | ocfs2_data_unlock(inode, 1); |
470 | out_unlock_meta: | 470 | out_unlock_meta: |
@@ -490,7 +490,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | |||
490 | * accessed concurrently from multiple nodes. | 490 | * accessed concurrently from multiple nodes. |
491 | */ | 491 | */ |
492 | if (!INODE_JOURNAL(inode)) { | 492 | if (!INODE_JOURNAL(inode)) { |
493 | err = ocfs2_meta_lock(inode, NULL, NULL, 0); | 493 | err = ocfs2_meta_lock(inode, NULL, 0); |
494 | if (err) { | 494 | if (err) { |
495 | if (err != -ENOENT) | 495 | if (err != -ENOENT) |
496 | mlog_errno(err); | 496 | mlog_errno(err); |
@@ -540,8 +540,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | |||
540 | struct buffer_head *bh_result, int create) | 540 | struct buffer_head *bh_result, int create) |
541 | { | 541 | { |
542 | int ret; | 542 | int ret; |
543 | u64 vbo_max; /* file offset, max_blocks from iblock */ | 543 | u64 p_blkno, inode_blocks; |
544 | u64 p_blkno; | ||
545 | int contig_blocks; | 544 | int contig_blocks; |
546 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 545 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
547 | unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; | 546 | unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; |
@@ -550,12 +549,23 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | |||
550 | * nicely aligned and of the right size, so there's no need | 549 | * nicely aligned and of the right size, so there's no need |
551 | * for us to check any of that. */ | 550 | * for us to check any of that. */ |
552 | 551 | ||
553 | vbo_max = ((u64)iblock + max_blocks) << blocksize_bits; | ||
554 | |||
555 | spin_lock(&OCFS2_I(inode)->ip_lock); | 552 | spin_lock(&OCFS2_I(inode)->ip_lock); |
556 | if ((iblock + max_blocks) > | 553 | inode_blocks = ocfs2_clusters_to_blocks(inode->i_sb, |
557 | ocfs2_clusters_to_blocks(inode->i_sb, | 554 | OCFS2_I(inode)->ip_clusters); |
558 | OCFS2_I(inode)->ip_clusters)) { | 555 | |
556 | /* | ||
557 | * For a read which begins past the end of file, we return a hole. | ||
558 | */ | ||
559 | if (!create && (iblock >= inode_blocks)) { | ||
560 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
561 | ret = 0; | ||
562 | goto bail; | ||
563 | } | ||
564 | |||
565 | /* | ||
566 | * Any write past EOF is not allowed because we'd be extending. | ||
567 | */ | ||
568 | if (create && (iblock + max_blocks) > inode_blocks) { | ||
559 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 569 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
560 | ret = -EIO; | 570 | ret = -EIO; |
561 | goto bail; | 571 | goto bail; |
@@ -595,7 +605,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
595 | ssize_t bytes, | 605 | ssize_t bytes, |
596 | void *private) | 606 | void *private) |
597 | { | 607 | { |
598 | struct inode *inode = iocb->ki_filp->f_dentry->d_inode; | 608 | struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; |
599 | 609 | ||
600 | /* this io's submitter should not have unlocked this before we could */ | 610 | /* this io's submitter should not have unlocked this before we could */ |
601 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); | 611 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); |
@@ -611,7 +621,7 @@ static ssize_t ocfs2_direct_IO(int rw, | |||
611 | unsigned long nr_segs) | 621 | unsigned long nr_segs) |
612 | { | 622 | { |
613 | struct file *file = iocb->ki_filp; | 623 | struct file *file = iocb->ki_filp; |
614 | struct inode *inode = file->f_dentry->d_inode->i_mapping->host; | 624 | struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; |
615 | int ret; | 625 | int ret; |
616 | 626 | ||
617 | mlog_entry_void(); | 627 | mlog_entry_void(); |
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index e88c3f0b8fa9..f446a15eab88 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h | |||
@@ -25,7 +25,7 @@ | |||
25 | int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, | 25 | int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, |
26 | unsigned from, unsigned to); | 26 | unsigned from, unsigned to); |
27 | 27 | ||
28 | struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | 28 | handle_t *ocfs2_start_walk_page_trans(struct inode *inode, |
29 | struct page *page, | 29 | struct page *page, |
30 | unsigned from, | 30 | unsigned from, |
31 | unsigned to); | 31 | unsigned to); |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 305cba3681fe..277ca67a2ad6 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -141,7 +141,7 @@ struct o2hb_region { | |||
141 | * recognizes a node going up and down in one iteration */ | 141 | * recognizes a node going up and down in one iteration */ |
142 | u64 hr_generation; | 142 | u64 hr_generation; |
143 | 143 | ||
144 | struct work_struct hr_write_timeout_work; | 144 | struct delayed_work hr_write_timeout_work; |
145 | unsigned long hr_last_timeout_start; | 145 | unsigned long hr_last_timeout_start; |
146 | 146 | ||
147 | /* Used during o2hb_check_slot to hold a copy of the block | 147 | /* Used during o2hb_check_slot to hold a copy of the block |
@@ -156,9 +156,11 @@ struct o2hb_bio_wait_ctxt { | |||
156 | int wc_error; | 156 | int wc_error; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static void o2hb_write_timeout(void *arg) | 159 | static void o2hb_write_timeout(struct work_struct *work) |
160 | { | 160 | { |
161 | struct o2hb_region *reg = arg; | 161 | struct o2hb_region *reg = |
162 | container_of(work, struct o2hb_region, | ||
163 | hr_write_timeout_work.work); | ||
162 | 164 | ||
163 | mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " | 165 | mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " |
164 | "milliseconds\n", reg->hr_dev_name, | 166 | "milliseconds\n", reg->hr_dev_name, |
@@ -1404,7 +1406,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1404 | goto out; | 1406 | goto out; |
1405 | } | 1407 | } |
1406 | 1408 | ||
1407 | INIT_WORK(®->hr_write_timeout_work, o2hb_write_timeout, reg); | 1409 | INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); |
1408 | 1410 | ||
1409 | /* | 1411 | /* |
1410 | * A node is considered live after it has beat LIVE_THRESHOLD | 1412 | * A node is considered live after it has beat LIVE_THRESHOLD |
@@ -1445,6 +1447,15 @@ out: | |||
1445 | return ret; | 1447 | return ret; |
1446 | } | 1448 | } |
1447 | 1449 | ||
1450 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | ||
1451 | char *page) | ||
1452 | { | ||
1453 | if (!reg->hr_task) | ||
1454 | return 0; | ||
1455 | |||
1456 | return sprintf(page, "%u\n", reg->hr_task->pid); | ||
1457 | } | ||
1458 | |||
1448 | struct o2hb_region_attribute { | 1459 | struct o2hb_region_attribute { |
1449 | struct configfs_attribute attr; | 1460 | struct configfs_attribute attr; |
1450 | ssize_t (*show)(struct o2hb_region *, char *); | 1461 | ssize_t (*show)(struct o2hb_region *, char *); |
@@ -1483,11 +1494,19 @@ static struct o2hb_region_attribute o2hb_region_attr_dev = { | |||
1483 | .store = o2hb_region_dev_write, | 1494 | .store = o2hb_region_dev_write, |
1484 | }; | 1495 | }; |
1485 | 1496 | ||
1497 | static struct o2hb_region_attribute o2hb_region_attr_pid = { | ||
1498 | .attr = { .ca_owner = THIS_MODULE, | ||
1499 | .ca_name = "pid", | ||
1500 | .ca_mode = S_IRUGO | S_IRUSR }, | ||
1501 | .show = o2hb_region_pid_read, | ||
1502 | }; | ||
1503 | |||
1486 | static struct configfs_attribute *o2hb_region_attrs[] = { | 1504 | static struct configfs_attribute *o2hb_region_attrs[] = { |
1487 | &o2hb_region_attr_block_bytes.attr, | 1505 | &o2hb_region_attr_block_bytes.attr, |
1488 | &o2hb_region_attr_start_block.attr, | 1506 | &o2hb_region_attr_start_block.attr, |
1489 | &o2hb_region_attr_blocks.attr, | 1507 | &o2hb_region_attr_blocks.attr, |
1490 | &o2hb_region_attr_dev.attr, | 1508 | &o2hb_region_attr_dev.attr, |
1509 | &o2hb_region_attr_pid.attr, | ||
1491 | NULL, | 1510 | NULL, |
1492 | }; | 1511 | }; |
1493 | 1512 | ||
@@ -1551,7 +1570,7 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g | |||
1551 | struct o2hb_region *reg = NULL; | 1570 | struct o2hb_region *reg = NULL; |
1552 | struct config_item *ret = NULL; | 1571 | struct config_item *ret = NULL; |
1553 | 1572 | ||
1554 | reg = kcalloc(1, sizeof(struct o2hb_region), GFP_KERNEL); | 1573 | reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); |
1555 | if (reg == NULL) | 1574 | if (reg == NULL) |
1556 | goto out; /* ENOMEM */ | 1575 | goto out; /* ENOMEM */ |
1557 | 1576 | ||
@@ -1677,7 +1696,7 @@ struct config_group *o2hb_alloc_hb_set(void) | |||
1677 | struct o2hb_heartbeat_group *hs = NULL; | 1696 | struct o2hb_heartbeat_group *hs = NULL; |
1678 | struct config_group *ret = NULL; | 1697 | struct config_group *ret = NULL; |
1679 | 1698 | ||
1680 | hs = kcalloc(1, sizeof(struct o2hb_heartbeat_group), GFP_KERNEL); | 1699 | hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL); |
1681 | if (hs == NULL) | 1700 | if (hs == NULL) |
1682 | goto out; | 1701 | goto out; |
1683 | 1702 | ||
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index d11753c50bc1..b17333a0606b 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
@@ -35,7 +35,7 @@ | |||
35 | /* for now we operate under the assertion that there can be only one | 35 | /* for now we operate under the assertion that there can be only one |
36 | * cluster active at a time. Changing this will require trickling | 36 | * cluster active at a time. Changing this will require trickling |
37 | * cluster references throughout where nodes are looked up */ | 37 | * cluster references throughout where nodes are looked up */ |
38 | static struct o2nm_cluster *o2nm_single_cluster = NULL; | 38 | struct o2nm_cluster *o2nm_single_cluster = NULL; |
39 | 39 | ||
40 | #define OCFS2_MAX_HB_CTL_PATH 256 | 40 | #define OCFS2_MAX_HB_CTL_PATH 256 |
41 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; | 41 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; |
@@ -97,17 +97,6 @@ const char *o2nm_get_hb_ctl_path(void) | |||
97 | } | 97 | } |
98 | EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path); | 98 | EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path); |
99 | 99 | ||
100 | struct o2nm_cluster { | ||
101 | struct config_group cl_group; | ||
102 | unsigned cl_has_local:1; | ||
103 | u8 cl_local_node; | ||
104 | rwlock_t cl_nodes_lock; | ||
105 | struct o2nm_node *cl_nodes[O2NM_MAX_NODES]; | ||
106 | struct rb_root cl_node_ip_tree; | ||
107 | /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ | ||
108 | unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; | ||
109 | }; | ||
110 | |||
111 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) | 100 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) |
112 | { | 101 | { |
113 | struct o2nm_node *node = NULL; | 102 | struct o2nm_node *node = NULL; |
@@ -543,6 +532,179 @@ static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group) | |||
543 | } | 532 | } |
544 | #endif | 533 | #endif |
545 | 534 | ||
535 | struct o2nm_cluster_attribute { | ||
536 | struct configfs_attribute attr; | ||
537 | ssize_t (*show)(struct o2nm_cluster *, char *); | ||
538 | ssize_t (*store)(struct o2nm_cluster *, const char *, size_t); | ||
539 | }; | ||
540 | |||
541 | static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count, | ||
542 | unsigned int *val) | ||
543 | { | ||
544 | unsigned long tmp; | ||
545 | char *p = (char *)page; | ||
546 | |||
547 | tmp = simple_strtoul(p, &p, 0); | ||
548 | if (!p || (*p && (*p != '\n'))) | ||
549 | return -EINVAL; | ||
550 | |||
551 | if (tmp == 0) | ||
552 | return -EINVAL; | ||
553 | if (tmp >= (u32)-1) | ||
554 | return -ERANGE; | ||
555 | |||
556 | *val = tmp; | ||
557 | |||
558 | return count; | ||
559 | } | ||
560 | |||
561 | static ssize_t o2nm_cluster_attr_idle_timeout_ms_read( | ||
562 | struct o2nm_cluster *cluster, char *page) | ||
563 | { | ||
564 | return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms); | ||
565 | } | ||
566 | |||
567 | static ssize_t o2nm_cluster_attr_idle_timeout_ms_write( | ||
568 | struct o2nm_cluster *cluster, const char *page, size_t count) | ||
569 | { | ||
570 | ssize_t ret; | ||
571 | unsigned int val; | ||
572 | |||
573 | ret = o2nm_cluster_attr_write(page, count, &val); | ||
574 | |||
575 | if (ret > 0) { | ||
576 | if (cluster->cl_idle_timeout_ms != val | ||
577 | && o2net_num_connected_peers()) { | ||
578 | mlog(ML_NOTICE, | ||
579 | "o2net: cannot change idle timeout after " | ||
580 | "the first peer has agreed to it." | ||
581 | " %d connected peers\n", | ||
582 | o2net_num_connected_peers()); | ||
583 | ret = -EINVAL; | ||
584 | } else if (val <= cluster->cl_keepalive_delay_ms) { | ||
585 | mlog(ML_NOTICE, "o2net: idle timeout must be larger " | ||
586 | "than keepalive delay\n"); | ||
587 | ret = -EINVAL; | ||
588 | } else { | ||
589 | cluster->cl_idle_timeout_ms = val; | ||
590 | } | ||
591 | } | ||
592 | |||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read( | ||
597 | struct o2nm_cluster *cluster, char *page) | ||
598 | { | ||
599 | return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms); | ||
600 | } | ||
601 | |||
602 | static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write( | ||
603 | struct o2nm_cluster *cluster, const char *page, size_t count) | ||
604 | { | ||
605 | ssize_t ret; | ||
606 | unsigned int val; | ||
607 | |||
608 | ret = o2nm_cluster_attr_write(page, count, &val); | ||
609 | |||
610 | if (ret > 0) { | ||
611 | if (cluster->cl_keepalive_delay_ms != val | ||
612 | && o2net_num_connected_peers()) { | ||
613 | mlog(ML_NOTICE, | ||
614 | "o2net: cannot change keepalive delay after" | ||
615 | " the first peer has agreed to it." | ||
616 | " %d connected peers\n", | ||
617 | o2net_num_connected_peers()); | ||
618 | ret = -EINVAL; | ||
619 | } else if (val >= cluster->cl_idle_timeout_ms) { | ||
620 | mlog(ML_NOTICE, "o2net: keepalive delay must be " | ||
621 | "smaller than idle timeout\n"); | ||
622 | ret = -EINVAL; | ||
623 | } else { | ||
624 | cluster->cl_keepalive_delay_ms = val; | ||
625 | } | ||
626 | } | ||
627 | |||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read( | ||
632 | struct o2nm_cluster *cluster, char *page) | ||
633 | { | ||
634 | return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms); | ||
635 | } | ||
636 | |||
637 | static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( | ||
638 | struct o2nm_cluster *cluster, const char *page, size_t count) | ||
639 | { | ||
640 | return o2nm_cluster_attr_write(page, count, | ||
641 | &cluster->cl_reconnect_delay_ms); | ||
642 | } | ||
643 | static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { | ||
644 | .attr = { .ca_owner = THIS_MODULE, | ||
645 | .ca_name = "idle_timeout_ms", | ||
646 | .ca_mode = S_IRUGO | S_IWUSR }, | ||
647 | .show = o2nm_cluster_attr_idle_timeout_ms_read, | ||
648 | .store = o2nm_cluster_attr_idle_timeout_ms_write, | ||
649 | }; | ||
650 | |||
651 | static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = { | ||
652 | .attr = { .ca_owner = THIS_MODULE, | ||
653 | .ca_name = "keepalive_delay_ms", | ||
654 | .ca_mode = S_IRUGO | S_IWUSR }, | ||
655 | .show = o2nm_cluster_attr_keepalive_delay_ms_read, | ||
656 | .store = o2nm_cluster_attr_keepalive_delay_ms_write, | ||
657 | }; | ||
658 | |||
659 | static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { | ||
660 | .attr = { .ca_owner = THIS_MODULE, | ||
661 | .ca_name = "reconnect_delay_ms", | ||
662 | .ca_mode = S_IRUGO | S_IWUSR }, | ||
663 | .show = o2nm_cluster_attr_reconnect_delay_ms_read, | ||
664 | .store = o2nm_cluster_attr_reconnect_delay_ms_write, | ||
665 | }; | ||
666 | |||
667 | static struct configfs_attribute *o2nm_cluster_attrs[] = { | ||
668 | &o2nm_cluster_attr_idle_timeout_ms.attr, | ||
669 | &o2nm_cluster_attr_keepalive_delay_ms.attr, | ||
670 | &o2nm_cluster_attr_reconnect_delay_ms.attr, | ||
671 | NULL, | ||
672 | }; | ||
673 | static ssize_t o2nm_cluster_show(struct config_item *item, | ||
674 | struct configfs_attribute *attr, | ||
675 | char *page) | ||
676 | { | ||
677 | struct o2nm_cluster *cluster = to_o2nm_cluster(item); | ||
678 | struct o2nm_cluster_attribute *o2nm_cluster_attr = | ||
679 | container_of(attr, struct o2nm_cluster_attribute, attr); | ||
680 | ssize_t ret = 0; | ||
681 | |||
682 | if (o2nm_cluster_attr->show) | ||
683 | ret = o2nm_cluster_attr->show(cluster, page); | ||
684 | return ret; | ||
685 | } | ||
686 | |||
687 | static ssize_t o2nm_cluster_store(struct config_item *item, | ||
688 | struct configfs_attribute *attr, | ||
689 | const char *page, size_t count) | ||
690 | { | ||
691 | struct o2nm_cluster *cluster = to_o2nm_cluster(item); | ||
692 | struct o2nm_cluster_attribute *o2nm_cluster_attr = | ||
693 | container_of(attr, struct o2nm_cluster_attribute, attr); | ||
694 | ssize_t ret; | ||
695 | |||
696 | if (o2nm_cluster_attr->store == NULL) { | ||
697 | ret = -EINVAL; | ||
698 | goto out; | ||
699 | } | ||
700 | |||
701 | ret = o2nm_cluster_attr->store(cluster, page, count); | ||
702 | if (ret < count) | ||
703 | goto out; | ||
704 | out: | ||
705 | return ret; | ||
706 | } | ||
707 | |||
546 | static struct config_item *o2nm_node_group_make_item(struct config_group *group, | 708 | static struct config_item *o2nm_node_group_make_item(struct config_group *group, |
547 | const char *name) | 709 | const char *name) |
548 | { | 710 | { |
@@ -552,7 +714,7 @@ static struct config_item *o2nm_node_group_make_item(struct config_group *group, | |||
552 | if (strlen(name) > O2NM_MAX_NAME_LEN) | 714 | if (strlen(name) > O2NM_MAX_NAME_LEN) |
553 | goto out; /* ENAMETOOLONG */ | 715 | goto out; /* ENAMETOOLONG */ |
554 | 716 | ||
555 | node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL); | 717 | node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); |
556 | if (node == NULL) | 718 | if (node == NULL) |
557 | goto out; /* ENOMEM */ | 719 | goto out; /* ENOMEM */ |
558 | 720 | ||
@@ -624,10 +786,13 @@ static void o2nm_cluster_release(struct config_item *item) | |||
624 | 786 | ||
625 | static struct configfs_item_operations o2nm_cluster_item_ops = { | 787 | static struct configfs_item_operations o2nm_cluster_item_ops = { |
626 | .release = o2nm_cluster_release, | 788 | .release = o2nm_cluster_release, |
789 | .show_attribute = o2nm_cluster_show, | ||
790 | .store_attribute = o2nm_cluster_store, | ||
627 | }; | 791 | }; |
628 | 792 | ||
629 | static struct config_item_type o2nm_cluster_type = { | 793 | static struct config_item_type o2nm_cluster_type = { |
630 | .ct_item_ops = &o2nm_cluster_item_ops, | 794 | .ct_item_ops = &o2nm_cluster_item_ops, |
795 | .ct_attrs = o2nm_cluster_attrs, | ||
631 | .ct_owner = THIS_MODULE, | 796 | .ct_owner = THIS_MODULE, |
632 | }; | 797 | }; |
633 | 798 | ||
@@ -660,8 +825,8 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g | |||
660 | if (o2nm_single_cluster) | 825 | if (o2nm_single_cluster) |
661 | goto out; /* ENOSPC */ | 826 | goto out; /* ENOSPC */ |
662 | 827 | ||
663 | cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL); | 828 | cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); |
664 | ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL); | 829 | ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); |
665 | defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); | 830 | defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); |
666 | o2hb_group = o2hb_alloc_hb_set(); | 831 | o2hb_group = o2hb_alloc_hb_set(); |
667 | if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) | 832 | if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) |
@@ -678,6 +843,9 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g | |||
678 | cluster->cl_group.default_groups[2] = NULL; | 843 | cluster->cl_group.default_groups[2] = NULL; |
679 | rwlock_init(&cluster->cl_nodes_lock); | 844 | rwlock_init(&cluster->cl_nodes_lock); |
680 | cluster->cl_node_ip_tree = RB_ROOT; | 845 | cluster->cl_node_ip_tree = RB_ROOT; |
846 | cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; | ||
847 | cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; | ||
848 | cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; | ||
681 | 849 | ||
682 | ret = &cluster->cl_group; | 850 | ret = &cluster->cl_group; |
683 | o2nm_single_cluster = cluster; | 851 | o2nm_single_cluster = cluster; |
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index fce8033c310f..8fb23cacc2f5 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h | |||
@@ -53,6 +53,23 @@ struct o2nm_node { | |||
53 | unsigned long nd_set_attributes; | 53 | unsigned long nd_set_attributes; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct o2nm_cluster { | ||
57 | struct config_group cl_group; | ||
58 | unsigned cl_has_local:1; | ||
59 | u8 cl_local_node; | ||
60 | rwlock_t cl_nodes_lock; | ||
61 | struct o2nm_node *cl_nodes[O2NM_MAX_NODES]; | ||
62 | struct rb_root cl_node_ip_tree; | ||
63 | unsigned int cl_idle_timeout_ms; | ||
64 | unsigned int cl_keepalive_delay_ms; | ||
65 | unsigned int cl_reconnect_delay_ms; | ||
66 | |||
67 | /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ | ||
68 | unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; | ||
69 | }; | ||
70 | |||
71 | extern struct o2nm_cluster *o2nm_single_cluster; | ||
72 | |||
56 | u8 o2nm_this_node(void); | 73 | u8 o2nm_this_node(void); |
57 | 74 | ||
58 | int o2nm_configured_node_map(unsigned long *map, unsigned bytes); | 75 | int o2nm_configured_node_map(unsigned long *map, unsigned bytes); |
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index 7bba98fbfc15..4705d659fe57 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c | |||
@@ -88,7 +88,7 @@ void o2quo_disk_timeout(void) | |||
88 | o2quo_fence_self(); | 88 | o2quo_fence_self(); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void o2quo_make_decision(void *arg) | 91 | static void o2quo_make_decision(struct work_struct *work) |
92 | { | 92 | { |
93 | int quorum; | 93 | int quorum; |
94 | int lowest_hb, lowest_reachable = 0, fence = 0; | 94 | int lowest_hb, lowest_reachable = 0, fence = 0; |
@@ -306,7 +306,7 @@ void o2quo_init(void) | |||
306 | struct o2quo_state *qs = &o2quo_state; | 306 | struct o2quo_state *qs = &o2quo_state; |
307 | 307 | ||
308 | spin_lock_init(&qs->qs_lock); | 308 | spin_lock_init(&qs->qs_lock); |
309 | INIT_WORK(&qs->qs_work, o2quo_make_decision, NULL); | 309 | INIT_WORK(&qs->qs_work, o2quo_make_decision); |
310 | } | 310 | } |
311 | 311 | ||
312 | void o2quo_exit(void) | 312 | void o2quo_exit(void) |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index b650efa8c8be..ae4ff4a6636b 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -140,13 +140,35 @@ static int o2net_sys_err_translations[O2NET_ERR_MAX] = | |||
140 | [O2NET_ERR_DIED] = -EHOSTDOWN,}; | 140 | [O2NET_ERR_DIED] = -EHOSTDOWN,}; |
141 | 141 | ||
142 | /* can't quite avoid *all* internal declarations :/ */ | 142 | /* can't quite avoid *all* internal declarations :/ */ |
143 | static void o2net_sc_connect_completed(void *arg); | 143 | static void o2net_sc_connect_completed(struct work_struct *work); |
144 | static void o2net_rx_until_empty(void *arg); | 144 | static void o2net_rx_until_empty(struct work_struct *work); |
145 | static void o2net_shutdown_sc(void *arg); | 145 | static void o2net_shutdown_sc(struct work_struct *work); |
146 | static void o2net_listen_data_ready(struct sock *sk, int bytes); | 146 | static void o2net_listen_data_ready(struct sock *sk, int bytes); |
147 | static void o2net_sc_send_keep_req(void *arg); | 147 | static void o2net_sc_send_keep_req(struct work_struct *work); |
148 | static void o2net_idle_timer(unsigned long data); | 148 | static void o2net_idle_timer(unsigned long data); |
149 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); | 149 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); |
150 | static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc); | ||
151 | |||
152 | /* | ||
153 | * FIXME: These should use to_o2nm_cluster_from_node(), but we end up | ||
154 | * losing our parent link to the cluster during shutdown. This can be | ||
155 | * solved by adding a pre-removal callback to configfs, or passing | ||
156 | * around the cluster with the node. -jeffm | ||
157 | */ | ||
158 | static inline int o2net_reconnect_delay(struct o2nm_node *node) | ||
159 | { | ||
160 | return o2nm_single_cluster->cl_reconnect_delay_ms; | ||
161 | } | ||
162 | |||
163 | static inline int o2net_keepalive_delay(struct o2nm_node *node) | ||
164 | { | ||
165 | return o2nm_single_cluster->cl_keepalive_delay_ms; | ||
166 | } | ||
167 | |||
168 | static inline int o2net_idle_timeout(struct o2nm_node *node) | ||
169 | { | ||
170 | return o2nm_single_cluster->cl_idle_timeout_ms; | ||
171 | } | ||
150 | 172 | ||
151 | static inline int o2net_sys_err_to_errno(enum o2net_system_error err) | 173 | static inline int o2net_sys_err_to_errno(enum o2net_system_error err) |
152 | { | 174 | { |
@@ -271,6 +293,8 @@ static void sc_kref_release(struct kref *kref) | |||
271 | { | 293 | { |
272 | struct o2net_sock_container *sc = container_of(kref, | 294 | struct o2net_sock_container *sc = container_of(kref, |
273 | struct o2net_sock_container, sc_kref); | 295 | struct o2net_sock_container, sc_kref); |
296 | BUG_ON(timer_pending(&sc->sc_idle_timeout)); | ||
297 | |||
274 | sclog(sc, "releasing\n"); | 298 | sclog(sc, "releasing\n"); |
275 | 299 | ||
276 | if (sc->sc_sock) { | 300 | if (sc->sc_sock) { |
@@ -300,7 +324,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) | |||
300 | struct page *page = NULL; | 324 | struct page *page = NULL; |
301 | 325 | ||
302 | page = alloc_page(GFP_NOFS); | 326 | page = alloc_page(GFP_NOFS); |
303 | sc = kcalloc(1, sizeof(*sc), GFP_NOFS); | 327 | sc = kzalloc(sizeof(*sc), GFP_NOFS); |
304 | if (sc == NULL || page == NULL) | 328 | if (sc == NULL || page == NULL) |
305 | goto out; | 329 | goto out; |
306 | 330 | ||
@@ -308,10 +332,10 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) | |||
308 | o2nm_node_get(node); | 332 | o2nm_node_get(node); |
309 | sc->sc_node = node; | 333 | sc->sc_node = node; |
310 | 334 | ||
311 | INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed, sc); | 335 | INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); |
312 | INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty, sc); | 336 | INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); |
313 | INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc, sc); | 337 | INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); |
314 | INIT_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req, sc); | 338 | INIT_DELAYED_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req); |
315 | 339 | ||
316 | init_timer(&sc->sc_idle_timeout); | 340 | init_timer(&sc->sc_idle_timeout); |
317 | sc->sc_idle_timeout.function = o2net_idle_timer; | 341 | sc->sc_idle_timeout.function = o2net_idle_timer; |
@@ -342,7 +366,7 @@ static void o2net_sc_queue_work(struct o2net_sock_container *sc, | |||
342 | sc_put(sc); | 366 | sc_put(sc); |
343 | } | 367 | } |
344 | static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, | 368 | static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, |
345 | struct work_struct *work, | 369 | struct delayed_work *work, |
346 | int delay) | 370 | int delay) |
347 | { | 371 | { |
348 | sc_get(sc); | 372 | sc_get(sc); |
@@ -350,12 +374,19 @@ static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, | |||
350 | sc_put(sc); | 374 | sc_put(sc); |
351 | } | 375 | } |
352 | static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, | 376 | static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, |
353 | struct work_struct *work) | 377 | struct delayed_work *work) |
354 | { | 378 | { |
355 | if (cancel_delayed_work(work)) | 379 | if (cancel_delayed_work(work)) |
356 | sc_put(sc); | 380 | sc_put(sc); |
357 | } | 381 | } |
358 | 382 | ||
383 | static atomic_t o2net_connected_peers = ATOMIC_INIT(0); | ||
384 | |||
385 | int o2net_num_connected_peers(void) | ||
386 | { | ||
387 | return atomic_read(&o2net_connected_peers); | ||
388 | } | ||
389 | |||
359 | static void o2net_set_nn_state(struct o2net_node *nn, | 390 | static void o2net_set_nn_state(struct o2net_node *nn, |
360 | struct o2net_sock_container *sc, | 391 | struct o2net_sock_container *sc, |
361 | unsigned valid, int err) | 392 | unsigned valid, int err) |
@@ -366,6 +397,11 @@ static void o2net_set_nn_state(struct o2net_node *nn, | |||
366 | 397 | ||
367 | assert_spin_locked(&nn->nn_lock); | 398 | assert_spin_locked(&nn->nn_lock); |
368 | 399 | ||
400 | if (old_sc && !sc) | ||
401 | atomic_dec(&o2net_connected_peers); | ||
402 | else if (!old_sc && sc) | ||
403 | atomic_inc(&o2net_connected_peers); | ||
404 | |||
369 | /* the node num comparison and single connect/accept path should stop | 405 | /* the node num comparison and single connect/accept path should stop |
370 | * an non-null sc from being overwritten with another */ | 406 | * an non-null sc from being overwritten with another */ |
371 | BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); | 407 | BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); |
@@ -424,9 +460,9 @@ static void o2net_set_nn_state(struct o2net_node *nn, | |||
424 | /* delay if we're withing a RECONNECT_DELAY of the | 460 | /* delay if we're withing a RECONNECT_DELAY of the |
425 | * last attempt */ | 461 | * last attempt */ |
426 | delay = (nn->nn_last_connect_attempt + | 462 | delay = (nn->nn_last_connect_attempt + |
427 | msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS)) | 463 | msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) |
428 | - jiffies; | 464 | - jiffies; |
429 | if (delay > msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS)) | 465 | if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) |
430 | delay = 0; | 466 | delay = 0; |
431 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); | 467 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); |
432 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); | 468 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); |
@@ -564,9 +600,11 @@ static void o2net_ensure_shutdown(struct o2net_node *nn, | |||
564 | * ourselves as state_change couldn't get the nn_lock and call set_nn_state | 600 | * ourselves as state_change couldn't get the nn_lock and call set_nn_state |
565 | * itself. | 601 | * itself. |
566 | */ | 602 | */ |
567 | static void o2net_shutdown_sc(void *arg) | 603 | static void o2net_shutdown_sc(struct work_struct *work) |
568 | { | 604 | { |
569 | struct o2net_sock_container *sc = arg; | 605 | struct o2net_sock_container *sc = |
606 | container_of(work, struct o2net_sock_container, | ||
607 | sc_shutdown_work); | ||
570 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); | 608 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); |
571 | 609 | ||
572 | sclog(sc, "shutting down\n"); | 610 | sclog(sc, "shutting down\n"); |
@@ -676,7 +714,7 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, | |||
676 | goto out; | 714 | goto out; |
677 | } | 715 | } |
678 | 716 | ||
679 | nmh = kcalloc(1, sizeof(struct o2net_msg_handler), GFP_NOFS); | 717 | nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS); |
680 | if (nmh == NULL) { | 718 | if (nmh == NULL) { |
681 | ret = -ENOMEM; | 719 | ret = -ENOMEM; |
682 | goto out; | 720 | goto out; |
@@ -1097,13 +1135,51 @@ static int o2net_check_handshake(struct o2net_sock_container *sc) | |||
1097 | return -1; | 1135 | return -1; |
1098 | } | 1136 | } |
1099 | 1137 | ||
1138 | /* | ||
1139 | * Ensure timeouts are consistent with other nodes, otherwise | ||
1140 | * we can end up with one node thinking that the other must be down, | ||
1141 | * but isn't. This can ultimately cause corruption. | ||
1142 | */ | ||
1143 | if (be32_to_cpu(hand->o2net_idle_timeout_ms) != | ||
1144 | o2net_idle_timeout(sc->sc_node)) { | ||
1145 | mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of " | ||
1146 | "%u ms, but we use %u ms locally. disconnecting\n", | ||
1147 | SC_NODEF_ARGS(sc), | ||
1148 | be32_to_cpu(hand->o2net_idle_timeout_ms), | ||
1149 | o2net_idle_timeout(sc->sc_node)); | ||
1150 | o2net_ensure_shutdown(nn, sc, -ENOTCONN); | ||
1151 | return -1; | ||
1152 | } | ||
1153 | |||
1154 | if (be32_to_cpu(hand->o2net_keepalive_delay_ms) != | ||
1155 | o2net_keepalive_delay(sc->sc_node)) { | ||
1156 | mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of " | ||
1157 | "%u ms, but we use %u ms locally. disconnecting\n", | ||
1158 | SC_NODEF_ARGS(sc), | ||
1159 | be32_to_cpu(hand->o2net_keepalive_delay_ms), | ||
1160 | o2net_keepalive_delay(sc->sc_node)); | ||
1161 | o2net_ensure_shutdown(nn, sc, -ENOTCONN); | ||
1162 | return -1; | ||
1163 | } | ||
1164 | |||
1165 | if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) != | ||
1166 | O2HB_MAX_WRITE_TIMEOUT_MS) { | ||
1167 | mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of " | ||
1168 | "%u ms, but we use %u ms locally. disconnecting\n", | ||
1169 | SC_NODEF_ARGS(sc), | ||
1170 | be32_to_cpu(hand->o2hb_heartbeat_timeout_ms), | ||
1171 | O2HB_MAX_WRITE_TIMEOUT_MS); | ||
1172 | o2net_ensure_shutdown(nn, sc, -ENOTCONN); | ||
1173 | return -1; | ||
1174 | } | ||
1175 | |||
1100 | sc->sc_handshake_ok = 1; | 1176 | sc->sc_handshake_ok = 1; |
1101 | 1177 | ||
1102 | spin_lock(&nn->nn_lock); | 1178 | spin_lock(&nn->nn_lock); |
1103 | /* set valid and queue the idle timers only if it hasn't been | 1179 | /* set valid and queue the idle timers only if it hasn't been |
1104 | * shut down already */ | 1180 | * shut down already */ |
1105 | if (nn->nn_sc == sc) { | 1181 | if (nn->nn_sc == sc) { |
1106 | o2net_sc_postpone_idle(sc); | 1182 | o2net_sc_reset_idle_timer(sc); |
1107 | o2net_set_nn_state(nn, sc, 1, 0); | 1183 | o2net_set_nn_state(nn, sc, 1, 0); |
1108 | } | 1184 | } |
1109 | spin_unlock(&nn->nn_lock); | 1185 | spin_unlock(&nn->nn_lock); |
@@ -1129,6 +1205,23 @@ static int o2net_advance_rx(struct o2net_sock_container *sc) | |||
1129 | sclog(sc, "receiving\n"); | 1205 | sclog(sc, "receiving\n"); |
1130 | do_gettimeofday(&sc->sc_tv_advance_start); | 1206 | do_gettimeofday(&sc->sc_tv_advance_start); |
1131 | 1207 | ||
1208 | if (unlikely(sc->sc_handshake_ok == 0)) { | ||
1209 | if(sc->sc_page_off < sizeof(struct o2net_handshake)) { | ||
1210 | data = page_address(sc->sc_page) + sc->sc_page_off; | ||
1211 | datalen = sizeof(struct o2net_handshake) - sc->sc_page_off; | ||
1212 | ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); | ||
1213 | if (ret > 0) | ||
1214 | sc->sc_page_off += ret; | ||
1215 | } | ||
1216 | |||
1217 | if (sc->sc_page_off == sizeof(struct o2net_handshake)) { | ||
1218 | o2net_check_handshake(sc); | ||
1219 | if (unlikely(sc->sc_handshake_ok == 0)) | ||
1220 | ret = -EPROTO; | ||
1221 | } | ||
1222 | goto out; | ||
1223 | } | ||
1224 | |||
1132 | /* do we need more header? */ | 1225 | /* do we need more header? */ |
1133 | if (sc->sc_page_off < sizeof(struct o2net_msg)) { | 1226 | if (sc->sc_page_off < sizeof(struct o2net_msg)) { |
1134 | data = page_address(sc->sc_page) + sc->sc_page_off; | 1227 | data = page_address(sc->sc_page) + sc->sc_page_off; |
@@ -1136,15 +1229,6 @@ static int o2net_advance_rx(struct o2net_sock_container *sc) | |||
1136 | ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); | 1229 | ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); |
1137 | if (ret > 0) { | 1230 | if (ret > 0) { |
1138 | sc->sc_page_off += ret; | 1231 | sc->sc_page_off += ret; |
1139 | |||
1140 | /* this working relies on the handshake being | ||
1141 | * smaller than the normal message header */ | ||
1142 | if (sc->sc_page_off >= sizeof(struct o2net_handshake)&& | ||
1143 | !sc->sc_handshake_ok && o2net_check_handshake(sc)) { | ||
1144 | ret = -EPROTO; | ||
1145 | goto out; | ||
1146 | } | ||
1147 | |||
1148 | /* only swab incoming here.. we can | 1232 | /* only swab incoming here.. we can |
1149 | * only get here once as we cross from | 1233 | * only get here once as we cross from |
1150 | * being under to over */ | 1234 | * being under to over */ |
@@ -1201,9 +1285,10 @@ out: | |||
1201 | /* this work func is triggerd by data ready. it reads until it can read no | 1285 | /* this work func is triggerd by data ready. it reads until it can read no |
1202 | * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing | 1286 | * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing |
1203 | * our work the work struct will be marked and we'll be called again. */ | 1287 | * our work the work struct will be marked and we'll be called again. */ |
1204 | static void o2net_rx_until_empty(void *arg) | 1288 | static void o2net_rx_until_empty(struct work_struct *work) |
1205 | { | 1289 | { |
1206 | struct o2net_sock_container *sc = arg; | 1290 | struct o2net_sock_container *sc = |
1291 | container_of(work, struct o2net_sock_container, sc_rx_work); | ||
1207 | int ret; | 1292 | int ret; |
1208 | 1293 | ||
1209 | do { | 1294 | do { |
@@ -1245,26 +1330,43 @@ static int o2net_set_nodelay(struct socket *sock) | |||
1245 | return ret; | 1330 | return ret; |
1246 | } | 1331 | } |
1247 | 1332 | ||
1333 | static void o2net_initialize_handshake(void) | ||
1334 | { | ||
1335 | o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( | ||
1336 | O2HB_MAX_WRITE_TIMEOUT_MS); | ||
1337 | o2net_hand->o2net_idle_timeout_ms = cpu_to_be32( | ||
1338 | o2net_idle_timeout(NULL)); | ||
1339 | o2net_hand->o2net_keepalive_delay_ms = cpu_to_be32( | ||
1340 | o2net_keepalive_delay(NULL)); | ||
1341 | o2net_hand->o2net_reconnect_delay_ms = cpu_to_be32( | ||
1342 | o2net_reconnect_delay(NULL)); | ||
1343 | } | ||
1344 | |||
1248 | /* ------------------------------------------------------------ */ | 1345 | /* ------------------------------------------------------------ */ |
1249 | 1346 | ||
1250 | /* called when a connect completes and after a sock is accepted. the | 1347 | /* called when a connect completes and after a sock is accepted. the |
1251 | * rx path will see the response and mark the sc valid */ | 1348 | * rx path will see the response and mark the sc valid */ |
1252 | static void o2net_sc_connect_completed(void *arg) | 1349 | static void o2net_sc_connect_completed(struct work_struct *work) |
1253 | { | 1350 | { |
1254 | struct o2net_sock_container *sc = arg; | 1351 | struct o2net_sock_container *sc = |
1352 | container_of(work, struct o2net_sock_container, | ||
1353 | sc_connect_work); | ||
1255 | 1354 | ||
1256 | mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", | 1355 | mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", |
1257 | (unsigned long long)O2NET_PROTOCOL_VERSION, | 1356 | (unsigned long long)O2NET_PROTOCOL_VERSION, |
1258 | (unsigned long long)be64_to_cpu(o2net_hand->connector_id)); | 1357 | (unsigned long long)be64_to_cpu(o2net_hand->connector_id)); |
1259 | 1358 | ||
1359 | o2net_initialize_handshake(); | ||
1260 | o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); | 1360 | o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); |
1261 | sc_put(sc); | 1361 | sc_put(sc); |
1262 | } | 1362 | } |
1263 | 1363 | ||
1264 | /* this is called as a work_struct func. */ | 1364 | /* this is called as a work_struct func. */ |
1265 | static void o2net_sc_send_keep_req(void *arg) | 1365 | static void o2net_sc_send_keep_req(struct work_struct *work) |
1266 | { | 1366 | { |
1267 | struct o2net_sock_container *sc = arg; | 1367 | struct o2net_sock_container *sc = |
1368 | container_of(work, struct o2net_sock_container, | ||
1369 | sc_keepalive_work.work); | ||
1268 | 1370 | ||
1269 | o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); | 1371 | o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); |
1270 | sc_put(sc); | 1372 | sc_put(sc); |
@@ -1280,8 +1382,10 @@ static void o2net_idle_timer(unsigned long data) | |||
1280 | 1382 | ||
1281 | do_gettimeofday(&now); | 1383 | do_gettimeofday(&now); |
1282 | 1384 | ||
1283 | printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for 10 " | 1385 | printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u " |
1284 | "seconds, shutting it down.\n", SC_NODEF_ARGS(sc)); | 1386 | "seconds, shutting it down.\n", SC_NODEF_ARGS(sc), |
1387 | o2net_idle_timeout(sc->sc_node) / 1000, | ||
1388 | o2net_idle_timeout(sc->sc_node) % 1000); | ||
1285 | mlog(ML_NOTICE, "here are some times that might help debug the " | 1389 | mlog(ML_NOTICE, "here are some times that might help debug the " |
1286 | "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " | 1390 | "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " |
1287 | "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n", | 1391 | "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n", |
@@ -1299,14 +1403,21 @@ static void o2net_idle_timer(unsigned long data) | |||
1299 | o2net_sc_queue_work(sc, &sc->sc_shutdown_work); | 1403 | o2net_sc_queue_work(sc, &sc->sc_shutdown_work); |
1300 | } | 1404 | } |
1301 | 1405 | ||
1302 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) | 1406 | static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) |
1303 | { | 1407 | { |
1304 | o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); | 1408 | o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); |
1305 | o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, | 1409 | o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, |
1306 | O2NET_KEEPALIVE_DELAY_SECS * HZ); | 1410 | msecs_to_jiffies(o2net_keepalive_delay(sc->sc_node))); |
1307 | do_gettimeofday(&sc->sc_tv_timer); | 1411 | do_gettimeofday(&sc->sc_tv_timer); |
1308 | mod_timer(&sc->sc_idle_timeout, | 1412 | mod_timer(&sc->sc_idle_timeout, |
1309 | jiffies + (O2NET_IDLE_TIMEOUT_SECS * HZ)); | 1413 | jiffies + msecs_to_jiffies(o2net_idle_timeout(sc->sc_node))); |
1414 | } | ||
1415 | |||
1416 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) | ||
1417 | { | ||
1418 | /* Only push out an existing timer */ | ||
1419 | if (timer_pending(&sc->sc_idle_timeout)) | ||
1420 | o2net_sc_reset_idle_timer(sc); | ||
1310 | } | 1421 | } |
1311 | 1422 | ||
1312 | /* this work func is kicked whenever a path sets the nn state which doesn't | 1423 | /* this work func is kicked whenever a path sets the nn state which doesn't |
@@ -1314,14 +1425,15 @@ static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) | |||
1314 | * having a connect attempt fail, etc. This centralizes the logic which decides | 1425 | * having a connect attempt fail, etc. This centralizes the logic which decides |
1315 | * if a connect attempt should be made or if we should give up and all future | 1426 | * if a connect attempt should be made or if we should give up and all future |
1316 | * transmit attempts should fail */ | 1427 | * transmit attempts should fail */ |
1317 | static void o2net_start_connect(void *arg) | 1428 | static void o2net_start_connect(struct work_struct *work) |
1318 | { | 1429 | { |
1319 | struct o2net_node *nn = arg; | 1430 | struct o2net_node *nn = |
1431 | container_of(work, struct o2net_node, nn_connect_work.work); | ||
1320 | struct o2net_sock_container *sc = NULL; | 1432 | struct o2net_sock_container *sc = NULL; |
1321 | struct o2nm_node *node = NULL, *mynode = NULL; | 1433 | struct o2nm_node *node = NULL, *mynode = NULL; |
1322 | struct socket *sock = NULL; | 1434 | struct socket *sock = NULL; |
1323 | struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; | 1435 | struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; |
1324 | int ret = 0; | 1436 | int ret = 0, stop; |
1325 | 1437 | ||
1326 | /* if we're greater we initiate tx, otherwise we accept */ | 1438 | /* if we're greater we initiate tx, otherwise we accept */ |
1327 | if (o2nm_this_node() <= o2net_num_from_nn(nn)) | 1439 | if (o2nm_this_node() <= o2net_num_from_nn(nn)) |
@@ -1342,10 +1454,9 @@ static void o2net_start_connect(void *arg) | |||
1342 | 1454 | ||
1343 | spin_lock(&nn->nn_lock); | 1455 | spin_lock(&nn->nn_lock); |
1344 | /* see if we already have one pending or have given up */ | 1456 | /* see if we already have one pending or have given up */ |
1345 | if (nn->nn_sc || nn->nn_persistent_error) | 1457 | stop = (nn->nn_sc || nn->nn_persistent_error); |
1346 | arg = NULL; | ||
1347 | spin_unlock(&nn->nn_lock); | 1458 | spin_unlock(&nn->nn_lock); |
1348 | if (arg == NULL) /* *shrug*, needed some indicator */ | 1459 | if (stop) |
1349 | goto out; | 1460 | goto out; |
1350 | 1461 | ||
1351 | nn->nn_last_connect_attempt = jiffies; | 1462 | nn->nn_last_connect_attempt = jiffies; |
@@ -1421,24 +1532,29 @@ out: | |||
1421 | return; | 1532 | return; |
1422 | } | 1533 | } |
1423 | 1534 | ||
1424 | static void o2net_connect_expired(void *arg) | 1535 | static void o2net_connect_expired(struct work_struct *work) |
1425 | { | 1536 | { |
1426 | struct o2net_node *nn = arg; | 1537 | struct o2net_node *nn = |
1538 | container_of(work, struct o2net_node, nn_connect_expired.work); | ||
1427 | 1539 | ||
1428 | spin_lock(&nn->nn_lock); | 1540 | spin_lock(&nn->nn_lock); |
1429 | if (!nn->nn_sc_valid) { | 1541 | if (!nn->nn_sc_valid) { |
1542 | struct o2nm_node *node = nn->nn_sc->sc_node; | ||
1430 | mlog(ML_ERROR, "no connection established with node %u after " | 1543 | mlog(ML_ERROR, "no connection established with node %u after " |
1431 | "%u seconds, giving up and returning errors.\n", | 1544 | "%u.%u seconds, giving up and returning errors.\n", |
1432 | o2net_num_from_nn(nn), O2NET_IDLE_TIMEOUT_SECS); | 1545 | o2net_num_from_nn(nn), |
1546 | o2net_idle_timeout(node) / 1000, | ||
1547 | o2net_idle_timeout(node) % 1000); | ||
1433 | 1548 | ||
1434 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); | 1549 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); |
1435 | } | 1550 | } |
1436 | spin_unlock(&nn->nn_lock); | 1551 | spin_unlock(&nn->nn_lock); |
1437 | } | 1552 | } |
1438 | 1553 | ||
1439 | static void o2net_still_up(void *arg) | 1554 | static void o2net_still_up(struct work_struct *work) |
1440 | { | 1555 | { |
1441 | struct o2net_node *nn = arg; | 1556 | struct o2net_node *nn = |
1557 | container_of(work, struct o2net_node, nn_still_up.work); | ||
1442 | 1558 | ||
1443 | o2quo_hb_still_up(o2net_num_from_nn(nn)); | 1559 | o2quo_hb_still_up(o2net_num_from_nn(nn)); |
1444 | } | 1560 | } |
@@ -1469,6 +1585,8 @@ static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num, | |||
1469 | 1585 | ||
1470 | if (node_num != o2nm_this_node()) | 1586 | if (node_num != o2nm_this_node()) |
1471 | o2net_disconnect_node(node); | 1587 | o2net_disconnect_node(node); |
1588 | |||
1589 | BUG_ON(atomic_read(&o2net_connected_peers) < 0); | ||
1472 | } | 1590 | } |
1473 | 1591 | ||
1474 | static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, | 1592 | static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, |
@@ -1480,14 +1598,14 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, | |||
1480 | 1598 | ||
1481 | /* ensure an immediate connect attempt */ | 1599 | /* ensure an immediate connect attempt */ |
1482 | nn->nn_last_connect_attempt = jiffies - | 1600 | nn->nn_last_connect_attempt = jiffies - |
1483 | (msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS) + 1); | 1601 | (msecs_to_jiffies(o2net_reconnect_delay(node)) + 1); |
1484 | 1602 | ||
1485 | if (node_num != o2nm_this_node()) { | 1603 | if (node_num != o2nm_this_node()) { |
1486 | /* heartbeat doesn't work unless a local node number is | 1604 | /* heartbeat doesn't work unless a local node number is |
1487 | * configured and doing so brings up the o2net_wq, so we can | 1605 | * configured and doing so brings up the o2net_wq, so we can |
1488 | * use it.. */ | 1606 | * use it.. */ |
1489 | queue_delayed_work(o2net_wq, &nn->nn_connect_expired, | 1607 | queue_delayed_work(o2net_wq, &nn->nn_connect_expired, |
1490 | O2NET_IDLE_TIMEOUT_SECS * HZ); | 1608 | msecs_to_jiffies(o2net_idle_timeout(node))); |
1491 | 1609 | ||
1492 | /* believe it or not, accept and node hearbeating testing | 1610 | /* believe it or not, accept and node hearbeating testing |
1493 | * can succeed for this node before we got here.. so | 1611 | * can succeed for this node before we got here.. so |
@@ -1632,6 +1750,7 @@ static int o2net_accept_one(struct socket *sock) | |||
1632 | o2net_register_callbacks(sc->sc_sock->sk, sc); | 1750 | o2net_register_callbacks(sc->sc_sock->sk, sc); |
1633 | o2net_sc_queue_work(sc, &sc->sc_rx_work); | 1751 | o2net_sc_queue_work(sc, &sc->sc_rx_work); |
1634 | 1752 | ||
1753 | o2net_initialize_handshake(); | ||
1635 | o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); | 1754 | o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); |
1636 | 1755 | ||
1637 | out: | 1756 | out: |
@@ -1644,9 +1763,9 @@ out: | |||
1644 | return ret; | 1763 | return ret; |
1645 | } | 1764 | } |
1646 | 1765 | ||
1647 | static void o2net_accept_many(void *arg) | 1766 | static void o2net_accept_many(struct work_struct *work) |
1648 | { | 1767 | { |
1649 | struct socket *sock = arg; | 1768 | struct socket *sock = o2net_listen_sock; |
1650 | while (o2net_accept_one(sock) == 0) | 1769 | while (o2net_accept_one(sock) == 0) |
1651 | cond_resched(); | 1770 | cond_resched(); |
1652 | } | 1771 | } |
@@ -1700,7 +1819,7 @@ static int o2net_open_listening_sock(__be16 port) | |||
1700 | write_unlock_bh(&sock->sk->sk_callback_lock); | 1819 | write_unlock_bh(&sock->sk->sk_callback_lock); |
1701 | 1820 | ||
1702 | o2net_listen_sock = sock; | 1821 | o2net_listen_sock = sock; |
1703 | INIT_WORK(&o2net_listen_work, o2net_accept_many, sock); | 1822 | INIT_WORK(&o2net_listen_work, o2net_accept_many); |
1704 | 1823 | ||
1705 | sock->sk->sk_reuse = 1; | 1824 | sock->sk->sk_reuse = 1; |
1706 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); | 1825 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); |
@@ -1799,9 +1918,9 @@ int o2net_init(void) | |||
1799 | 1918 | ||
1800 | o2quo_init(); | 1919 | o2quo_init(); |
1801 | 1920 | ||
1802 | o2net_hand = kcalloc(1, sizeof(struct o2net_handshake), GFP_KERNEL); | 1921 | o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL); |
1803 | o2net_keep_req = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL); | 1922 | o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); |
1804 | o2net_keep_resp = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL); | 1923 | o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); |
1805 | if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) { | 1924 | if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) { |
1806 | kfree(o2net_hand); | 1925 | kfree(o2net_hand); |
1807 | kfree(o2net_keep_req); | 1926 | kfree(o2net_keep_req); |
@@ -1819,9 +1938,10 @@ int o2net_init(void) | |||
1819 | struct o2net_node *nn = o2net_nn_from_num(i); | 1938 | struct o2net_node *nn = o2net_nn_from_num(i); |
1820 | 1939 | ||
1821 | spin_lock_init(&nn->nn_lock); | 1940 | spin_lock_init(&nn->nn_lock); |
1822 | INIT_WORK(&nn->nn_connect_work, o2net_start_connect, nn); | 1941 | INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect); |
1823 | INIT_WORK(&nn->nn_connect_expired, o2net_connect_expired, nn); | 1942 | INIT_DELAYED_WORK(&nn->nn_connect_expired, |
1824 | INIT_WORK(&nn->nn_still_up, o2net_still_up, nn); | 1943 | o2net_connect_expired); |
1944 | INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up); | ||
1825 | /* until we see hb from a node we'll return einval */ | 1945 | /* until we see hb from a node we'll return einval */ |
1826 | nn->nn_persistent_error = -ENOTCONN; | 1946 | nn->nn_persistent_error = -ENOTCONN; |
1827 | init_waitqueue_head(&nn->nn_sc_wq); | 1947 | init_waitqueue_head(&nn->nn_sc_wq); |
diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h index 616ff2b8434a..21a4e43df836 100644 --- a/fs/ocfs2/cluster/tcp.h +++ b/fs/ocfs2/cluster/tcp.h | |||
@@ -54,6 +54,13 @@ typedef int (o2net_msg_handler_func)(struct o2net_msg *msg, u32 len, void *data) | |||
54 | 54 | ||
55 | #define O2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct o2net_msg)) | 55 | #define O2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct o2net_msg)) |
56 | 56 | ||
57 | /* same as hb delay, we're waiting for another node to recognize our hb */ | ||
58 | #define O2NET_RECONNECT_DELAY_MS_DEFAULT 2000 | ||
59 | |||
60 | #define O2NET_KEEPALIVE_DELAY_MS_DEFAULT 5000 | ||
61 | #define O2NET_IDLE_TIMEOUT_MS_DEFAULT 10000 | ||
62 | |||
63 | |||
57 | /* TODO: figure this out.... */ | 64 | /* TODO: figure this out.... */ |
58 | static inline int o2net_link_down(int err, struct socket *sock) | 65 | static inline int o2net_link_down(int err, struct socket *sock) |
59 | { | 66 | { |
@@ -101,6 +108,7 @@ void o2net_unregister_hb_callbacks(void); | |||
101 | int o2net_start_listening(struct o2nm_node *node); | 108 | int o2net_start_listening(struct o2nm_node *node); |
102 | void o2net_stop_listening(struct o2nm_node *node); | 109 | void o2net_stop_listening(struct o2nm_node *node); |
103 | void o2net_disconnect_node(struct o2nm_node *node); | 110 | void o2net_disconnect_node(struct o2nm_node *node); |
111 | int o2net_num_connected_peers(void); | ||
104 | 112 | ||
105 | int o2net_init(void); | 113 | int o2net_init(void); |
106 | void o2net_exit(void); | 114 | void o2net_exit(void); |
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index 4b46aac7d243..b700dc9624d1 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h | |||
@@ -27,23 +27,20 @@ | |||
27 | #define O2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) | 27 | #define O2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) |
28 | #define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) | 28 | #define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) |
29 | 29 | ||
30 | /* same as hb delay, we're waiting for another node to recognize our hb */ | ||
31 | #define O2NET_RECONNECT_DELAY_MS O2HB_REGION_TIMEOUT_MS | ||
32 | |||
33 | /* we're delaying our quorum decision so that heartbeat will have timed | 30 | /* we're delaying our quorum decision so that heartbeat will have timed |
34 | * out truly dead nodes by the time we come around to making decisions | 31 | * out truly dead nodes by the time we come around to making decisions |
35 | * on their number */ | 32 | * on their number */ |
36 | #define O2NET_QUORUM_DELAY_MS ((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS) | 33 | #define O2NET_QUORUM_DELAY_MS ((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS) |
37 | 34 | ||
38 | #define O2NET_KEEPALIVE_DELAY_SECS 5 | ||
39 | #define O2NET_IDLE_TIMEOUT_SECS 10 | ||
40 | |||
41 | /* | 35 | /* |
42 | * This version number represents quite a lot, unfortunately. It not | 36 | * This version number represents quite a lot, unfortunately. It not |
43 | * only represents the raw network message protocol on the wire but also | 37 | * only represents the raw network message protocol on the wire but also |
44 | * locking semantics of the file system using the protocol. It should | 38 | * locking semantics of the file system using the protocol. It should |
45 | * be somewhere else, I'm sure, but right now it isn't. | 39 | * be somewhere else, I'm sure, but right now it isn't. |
46 | * | 40 | * |
41 | * New in version 5: | ||
42 | * - Network timeout checking protocol | ||
43 | * | ||
47 | * New in version 4: | 44 | * New in version 4: |
48 | * - Remove i_generation from lock names for better stat performance. | 45 | * - Remove i_generation from lock names for better stat performance. |
49 | * | 46 | * |
@@ -54,10 +51,14 @@ | |||
54 | * - full 64 bit i_size in the metadata lock lvbs | 51 | * - full 64 bit i_size in the metadata lock lvbs |
55 | * - introduction of "rw" lock and pushing meta/data locking down | 52 | * - introduction of "rw" lock and pushing meta/data locking down |
56 | */ | 53 | */ |
57 | #define O2NET_PROTOCOL_VERSION 4ULL | 54 | #define O2NET_PROTOCOL_VERSION 5ULL |
58 | struct o2net_handshake { | 55 | struct o2net_handshake { |
59 | __be64 protocol_version; | 56 | __be64 protocol_version; |
60 | __be64 connector_id; | 57 | __be64 connector_id; |
58 | __be32 o2hb_heartbeat_timeout_ms; | ||
59 | __be32 o2net_idle_timeout_ms; | ||
60 | __be32 o2net_keepalive_delay_ms; | ||
61 | __be32 o2net_reconnect_delay_ms; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | struct o2net_node { | 64 | struct o2net_node { |
@@ -86,18 +87,18 @@ struct o2net_node { | |||
86 | * connect attempt fails and so can be self-arming. shutdown is | 87 | * connect attempt fails and so can be self-arming. shutdown is |
87 | * careful to first mark the nn such that no connects will be attempted | 88 | * careful to first mark the nn such that no connects will be attempted |
88 | * before canceling delayed connect work and flushing the queue. */ | 89 | * before canceling delayed connect work and flushing the queue. */ |
89 | struct work_struct nn_connect_work; | 90 | struct delayed_work nn_connect_work; |
90 | unsigned long nn_last_connect_attempt; | 91 | unsigned long nn_last_connect_attempt; |
91 | 92 | ||
92 | /* this is queued as nodes come up and is canceled when a connection is | 93 | /* this is queued as nodes come up and is canceled when a connection is |
93 | * established. this expiring gives up on the node and errors out | 94 | * established. this expiring gives up on the node and errors out |
94 | * transmits */ | 95 | * transmits */ |
95 | struct work_struct nn_connect_expired; | 96 | struct delayed_work nn_connect_expired; |
96 | 97 | ||
97 | /* after we give up on a socket we wait a while before deciding | 98 | /* after we give up on a socket we wait a while before deciding |
98 | * that it is still heartbeating and that we should do some | 99 | * that it is still heartbeating and that we should do some |
99 | * quorum work */ | 100 | * quorum work */ |
100 | struct work_struct nn_still_up; | 101 | struct delayed_work nn_still_up; |
101 | }; | 102 | }; |
102 | 103 | ||
103 | struct o2net_sock_container { | 104 | struct o2net_sock_container { |
@@ -129,7 +130,7 @@ struct o2net_sock_container { | |||
129 | struct work_struct sc_shutdown_work; | 130 | struct work_struct sc_shutdown_work; |
130 | 131 | ||
131 | struct timer_list sc_idle_timeout; | 132 | struct timer_list sc_idle_timeout; |
132 | struct work_struct sc_keepalive_work; | 133 | struct delayed_work sc_keepalive_work; |
133 | 134 | ||
134 | unsigned sc_handshake_ok:1; | 135 | unsigned sc_handshake_ok:1; |
135 | 136 | ||
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 04e01915b86e..66821e178167 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -79,9 +79,10 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
79 | struct buffer_head * bh, * tmp; | 79 | struct buffer_head * bh, * tmp; |
80 | struct ocfs2_dir_entry * de; | 80 | struct ocfs2_dir_entry * de; |
81 | int err; | 81 | int err; |
82 | struct inode *inode = filp->f_dentry->d_inode; | 82 | struct inode *inode = filp->f_path.dentry->d_inode; |
83 | struct super_block * sb = inode->i_sb; | 83 | struct super_block * sb = inode->i_sb; |
84 | unsigned int ra_sectors = 16; | 84 | unsigned int ra_sectors = 16; |
85 | int lock_level = 0; | ||
85 | 86 | ||
86 | mlog_entry("dirino=%llu\n", | 87 | mlog_entry("dirino=%llu\n", |
87 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 88 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
@@ -89,7 +90,15 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
89 | stored = 0; | 90 | stored = 0; |
90 | bh = NULL; | 91 | bh = NULL; |
91 | 92 | ||
92 | error = ocfs2_meta_lock(inode, NULL, NULL, 0); | 93 | error = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level); |
94 | if (lock_level && error >= 0) { | ||
95 | /* We release EX lock which used to update atime | ||
96 | * and get PR lock again to reduce contention | ||
97 | * on commonly accessed directories. */ | ||
98 | ocfs2_meta_unlock(inode, 1); | ||
99 | lock_level = 0; | ||
100 | error = ocfs2_meta_lock(inode, NULL, 0); | ||
101 | } | ||
93 | if (error < 0) { | 102 | if (error < 0) { |
94 | if (error != -ENOENT) | 103 | if (error != -ENOENT) |
95 | mlog_errno(error); | 104 | mlog_errno(error); |
@@ -198,7 +207,7 @@ revalidate: | |||
198 | 207 | ||
199 | stored = 0; | 208 | stored = 0; |
200 | bail: | 209 | bail: |
201 | ocfs2_meta_unlock(inode, 0); | 210 | ocfs2_meta_unlock(inode, lock_level); |
202 | 211 | ||
203 | bail_nolock: | 212 | bail_nolock: |
204 | mlog_exit(stored); | 213 | mlog_exit(stored); |
@@ -340,7 +349,7 @@ int ocfs2_empty_dir(struct inode *inode) | |||
340 | 349 | ||
341 | /* returns a bh of the 1st new block in the allocation. */ | 350 | /* returns a bh of the 1st new block in the allocation. */ |
342 | int ocfs2_do_extend_dir(struct super_block *sb, | 351 | int ocfs2_do_extend_dir(struct super_block *sb, |
343 | struct ocfs2_journal_handle *handle, | 352 | handle_t *handle, |
344 | struct inode *dir, | 353 | struct inode *dir, |
345 | struct buffer_head *parent_fe_bh, | 354 | struct buffer_head *parent_fe_bh, |
346 | struct ocfs2_alloc_context *data_ac, | 355 | struct ocfs2_alloc_context *data_ac, |
@@ -398,7 +407,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
398 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 407 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
399 | struct ocfs2_alloc_context *data_ac = NULL; | 408 | struct ocfs2_alloc_context *data_ac = NULL; |
400 | struct ocfs2_alloc_context *meta_ac = NULL; | 409 | struct ocfs2_alloc_context *meta_ac = NULL; |
401 | struct ocfs2_journal_handle *handle = NULL; | 410 | handle_t *handle = NULL; |
402 | struct buffer_head *new_bh = NULL; | 411 | struct buffer_head *new_bh = NULL; |
403 | struct ocfs2_dir_entry * de; | 412 | struct ocfs2_dir_entry * de; |
404 | struct super_block *sb = osb->sb; | 413 | struct super_block *sb = osb->sb; |
@@ -409,13 +418,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
409 | mlog(0, "extending dir %llu (i_size = %lld)\n", | 418 | mlog(0, "extending dir %llu (i_size = %lld)\n", |
410 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); | 419 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); |
411 | 420 | ||
412 | handle = ocfs2_alloc_handle(osb); | ||
413 | if (handle == NULL) { | ||
414 | status = -ENOMEM; | ||
415 | mlog_errno(status); | ||
416 | goto bail; | ||
417 | } | ||
418 | |||
419 | /* dir->i_size is always block aligned. */ | 421 | /* dir->i_size is always block aligned. */ |
420 | spin_lock(&OCFS2_I(dir)->ip_lock); | 422 | spin_lock(&OCFS2_I(dir)->ip_lock); |
421 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { | 423 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { |
@@ -428,8 +430,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
428 | } | 430 | } |
429 | 431 | ||
430 | if (!num_free_extents) { | 432 | if (!num_free_extents) { |
431 | status = ocfs2_reserve_new_metadata(osb, handle, | 433 | status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); |
432 | fe, &meta_ac); | ||
433 | if (status < 0) { | 434 | if (status < 0) { |
434 | if (status != -ENOSPC) | 435 | if (status != -ENOSPC) |
435 | mlog_errno(status); | 436 | mlog_errno(status); |
@@ -437,7 +438,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
437 | } | 438 | } |
438 | } | 439 | } |
439 | 440 | ||
440 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 441 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
441 | if (status < 0) { | 442 | if (status < 0) { |
442 | if (status != -ENOSPC) | 443 | if (status != -ENOSPC) |
443 | mlog_errno(status); | 444 | mlog_errno(status); |
@@ -450,7 +451,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
450 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; | 451 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; |
451 | } | 452 | } |
452 | 453 | ||
453 | handle = ocfs2_start_trans(osb, handle, credits); | 454 | handle = ocfs2_start_trans(osb, credits); |
454 | if (IS_ERR(handle)) { | 455 | if (IS_ERR(handle)) { |
455 | status = PTR_ERR(handle); | 456 | status = PTR_ERR(handle); |
456 | handle = NULL; | 457 | handle = NULL; |
@@ -496,7 +497,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
496 | get_bh(*new_de_bh); | 497 | get_bh(*new_de_bh); |
497 | bail: | 498 | bail: |
498 | if (handle) | 499 | if (handle) |
499 | ocfs2_commit_trans(handle); | 500 | ocfs2_commit_trans(osb, handle); |
500 | 501 | ||
501 | if (data_ac) | 502 | if (data_ac) |
502 | ocfs2_free_alloc_context(data_ac); | 503 | ocfs2_free_alloc_context(data_ac); |
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h index 5f614ec9649c..3f67e146864a 100644 --- a/fs/ocfs2/dir.h +++ b/fs/ocfs2/dir.h | |||
@@ -45,7 +45,7 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb, | |||
45 | struct buffer_head **ret_de_bh); | 45 | struct buffer_head **ret_de_bh); |
46 | struct ocfs2_alloc_context; | 46 | struct ocfs2_alloc_context; |
47 | int ocfs2_do_extend_dir(struct super_block *sb, | 47 | int ocfs2_do_extend_dir(struct super_block *sb, |
48 | struct ocfs2_journal_handle *handle, | 48 | handle_t *handle, |
49 | struct inode *dir, | 49 | struct inode *dir, |
50 | struct buffer_head *parent_fe_bh, | 50 | struct buffer_head *parent_fe_bh, |
51 | struct ocfs2_alloc_context *data_ac, | 51 | struct ocfs2_alloc_context *data_ac, |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index fa968180b072..6b6ff76538c5 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -153,7 +153,7 @@ static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned | |||
153 | * called functions that cannot be directly called from the | 153 | * called functions that cannot be directly called from the |
154 | * net message handlers for some reason, usually because | 154 | * net message handlers for some reason, usually because |
155 | * they need to send net messages of their own. */ | 155 | * they need to send net messages of their own. */ |
156 | void dlm_dispatch_work(void *data); | 156 | void dlm_dispatch_work(struct work_struct *work); |
157 | 157 | ||
158 | struct dlm_lock_resource; | 158 | struct dlm_lock_resource; |
159 | struct dlm_work_item; | 159 | struct dlm_work_item; |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 8d1065f8b3bd..f0b25f2dd205 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -68,7 +68,8 @@ static void **dlm_alloc_pagevec(int pages) | |||
68 | goto out_free; | 68 | goto out_free; |
69 | 69 | ||
70 | mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n", | 70 | mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n", |
71 | pages, DLM_HASH_PAGES, (unsigned long)DLM_BUCKETS_PER_PAGE); | 71 | pages, (unsigned long)DLM_HASH_PAGES, |
72 | (unsigned long)DLM_BUCKETS_PER_PAGE); | ||
72 | return vec; | 73 | return vec; |
73 | out_free: | 74 | out_free: |
74 | dlm_free_pagevec(vec, i); | 75 | dlm_free_pagevec(vec, i); |
@@ -919,7 +920,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) | |||
919 | 920 | ||
920 | mlog_entry("%p", dlm); | 921 | mlog_entry("%p", dlm); |
921 | 922 | ||
922 | ctxt = kcalloc(1, sizeof(*ctxt), GFP_KERNEL); | 923 | ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); |
923 | if (!ctxt) { | 924 | if (!ctxt) { |
924 | status = -ENOMEM; | 925 | status = -ENOMEM; |
925 | mlog_errno(status); | 926 | mlog_errno(status); |
@@ -1222,7 +1223,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, | |||
1222 | int i; | 1223 | int i; |
1223 | struct dlm_ctxt *dlm = NULL; | 1224 | struct dlm_ctxt *dlm = NULL; |
1224 | 1225 | ||
1225 | dlm = kcalloc(1, sizeof(*dlm), GFP_KERNEL); | 1226 | dlm = kzalloc(sizeof(*dlm), GFP_KERNEL); |
1226 | if (!dlm) { | 1227 | if (!dlm) { |
1227 | mlog_errno(-ENOMEM); | 1228 | mlog_errno(-ENOMEM); |
1228 | goto leave; | 1229 | goto leave; |
@@ -1296,7 +1297,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, | |||
1296 | 1297 | ||
1297 | spin_lock_init(&dlm->work_lock); | 1298 | spin_lock_init(&dlm->work_lock); |
1298 | INIT_LIST_HEAD(&dlm->work_list); | 1299 | INIT_LIST_HEAD(&dlm->work_list); |
1299 | INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work, dlm); | 1300 | INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work); |
1300 | 1301 | ||
1301 | kref_init(&dlm->dlm_refs); | 1302 | kref_init(&dlm->dlm_refs); |
1302 | dlm->dlm_state = DLM_CTXT_NEW; | 1303 | dlm->dlm_state = DLM_CTXT_NEW; |
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 16b8d1ba7066..b7f0ba97a1a2 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -66,7 +66,7 @@ static struct file_operations dlmfs_file_operations; | |||
66 | static struct inode_operations dlmfs_dir_inode_operations; | 66 | static struct inode_operations dlmfs_dir_inode_operations; |
67 | static struct inode_operations dlmfs_root_inode_operations; | 67 | static struct inode_operations dlmfs_root_inode_operations; |
68 | static struct inode_operations dlmfs_file_inode_operations; | 68 | static struct inode_operations dlmfs_file_inode_operations; |
69 | static kmem_cache_t *dlmfs_inode_cache; | 69 | static struct kmem_cache *dlmfs_inode_cache; |
70 | 70 | ||
71 | struct workqueue_struct *user_dlm_worker; | 71 | struct workqueue_struct *user_dlm_worker; |
72 | 72 | ||
@@ -176,7 +176,7 @@ static ssize_t dlmfs_file_read(struct file *filp, | |||
176 | int bytes_left; | 176 | int bytes_left; |
177 | ssize_t readlen; | 177 | ssize_t readlen; |
178 | char *lvb_buf; | 178 | char *lvb_buf; |
179 | struct inode *inode = filp->f_dentry->d_inode; | 179 | struct inode *inode = filp->f_path.dentry->d_inode; |
180 | 180 | ||
181 | mlog(0, "inode %lu, count = %zu, *ppos = %llu\n", | 181 | mlog(0, "inode %lu, count = %zu, *ppos = %llu\n", |
182 | inode->i_ino, count, *ppos); | 182 | inode->i_ino, count, *ppos); |
@@ -220,7 +220,7 @@ static ssize_t dlmfs_file_write(struct file *filp, | |||
220 | int bytes_left; | 220 | int bytes_left; |
221 | ssize_t writelen; | 221 | ssize_t writelen; |
222 | char *lvb_buf; | 222 | char *lvb_buf; |
223 | struct inode *inode = filp->f_dentry->d_inode; | 223 | struct inode *inode = filp->f_path.dentry->d_inode; |
224 | 224 | ||
225 | mlog(0, "inode %lu, count = %zu, *ppos = %llu\n", | 225 | mlog(0, "inode %lu, count = %zu, *ppos = %llu\n", |
226 | inode->i_ino, count, *ppos); | 226 | inode->i_ino, count, *ppos); |
@@ -257,7 +257,7 @@ static ssize_t dlmfs_file_write(struct file *filp, | |||
257 | } | 257 | } |
258 | 258 | ||
259 | static void dlmfs_init_once(void *foo, | 259 | static void dlmfs_init_once(void *foo, |
260 | kmem_cache_t *cachep, | 260 | struct kmem_cache *cachep, |
261 | unsigned long flags) | 261 | unsigned long flags) |
262 | { | 262 | { |
263 | struct dlmfs_inode_private *ip = | 263 | struct dlmfs_inode_private *ip = |
@@ -276,7 +276,7 @@ static struct inode *dlmfs_alloc_inode(struct super_block *sb) | |||
276 | { | 276 | { |
277 | struct dlmfs_inode_private *ip; | 277 | struct dlmfs_inode_private *ip; |
278 | 278 | ||
279 | ip = kmem_cache_alloc(dlmfs_inode_cache, SLAB_NOFS); | 279 | ip = kmem_cache_alloc(dlmfs_inode_cache, GFP_NOFS); |
280 | if (!ip) | 280 | if (!ip) |
281 | return NULL; | 281 | return NULL; |
282 | 282 | ||
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 42a1b91979b5..e5ca3db197f6 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c | |||
@@ -408,13 +408,13 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie, | |||
408 | struct dlm_lock *lock; | 408 | struct dlm_lock *lock; |
409 | int kernel_allocated = 0; | 409 | int kernel_allocated = 0; |
410 | 410 | ||
411 | lock = kcalloc(1, sizeof(*lock), GFP_NOFS); | 411 | lock = kzalloc(sizeof(*lock), GFP_NOFS); |
412 | if (!lock) | 412 | if (!lock) |
413 | return NULL; | 413 | return NULL; |
414 | 414 | ||
415 | if (!lksb) { | 415 | if (!lksb) { |
416 | /* zero memory only if kernel-allocated */ | 416 | /* zero memory only if kernel-allocated */ |
417 | lksb = kcalloc(1, sizeof(*lksb), GFP_NOFS); | 417 | lksb = kzalloc(sizeof(*lksb), GFP_NOFS); |
418 | if (!lksb) { | 418 | if (!lksb) { |
419 | kfree(lock); | 419 | kfree(lock); |
420 | return NULL; | 420 | return NULL; |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index f784177b6241..0ad872055cb3 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -221,7 +221,7 @@ EXPORT_SYMBOL_GPL(dlm_dump_all_mles); | |||
221 | #endif /* 0 */ | 221 | #endif /* 0 */ |
222 | 222 | ||
223 | 223 | ||
224 | static kmem_cache_t *dlm_mle_cache = NULL; | 224 | static struct kmem_cache *dlm_mle_cache = NULL; |
225 | 225 | ||
226 | 226 | ||
227 | static void dlm_mle_release(struct kref *kref); | 227 | static void dlm_mle_release(struct kref *kref); |
@@ -1939,7 +1939,7 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, | |||
1939 | int ignore_higher, u8 request_from, u32 flags) | 1939 | int ignore_higher, u8 request_from, u32 flags) |
1940 | { | 1940 | { |
1941 | struct dlm_work_item *item; | 1941 | struct dlm_work_item *item; |
1942 | item = kcalloc(1, sizeof(*item), GFP_NOFS); | 1942 | item = kzalloc(sizeof(*item), GFP_NOFS); |
1943 | if (!item) | 1943 | if (!item) |
1944 | return -ENOMEM; | 1944 | return -ENOMEM; |
1945 | 1945 | ||
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 9d950d7cea38..367a11e9e2ed 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -153,9 +153,10 @@ static inline void dlm_reset_recovery(struct dlm_ctxt *dlm) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /* Worker function used during recovery. */ | 155 | /* Worker function used during recovery. */ |
156 | void dlm_dispatch_work(void *data) | 156 | void dlm_dispatch_work(struct work_struct *work) |
157 | { | 157 | { |
158 | struct dlm_ctxt *dlm = (struct dlm_ctxt *)data; | 158 | struct dlm_ctxt *dlm = |
159 | container_of(work, struct dlm_ctxt, dispatched_work); | ||
159 | LIST_HEAD(tmp_list); | 160 | LIST_HEAD(tmp_list); |
160 | struct list_head *iter, *iter2; | 161 | struct list_head *iter, *iter2; |
161 | struct dlm_work_item *item; | 162 | struct dlm_work_item *item; |
@@ -756,7 +757,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node) | |||
756 | } | 757 | } |
757 | BUG_ON(num == dead_node); | 758 | BUG_ON(num == dead_node); |
758 | 759 | ||
759 | ndata = kcalloc(1, sizeof(*ndata), GFP_NOFS); | 760 | ndata = kzalloc(sizeof(*ndata), GFP_NOFS); |
760 | if (!ndata) { | 761 | if (!ndata) { |
761 | dlm_destroy_recovery_area(dlm, dead_node); | 762 | dlm_destroy_recovery_area(dlm, dead_node); |
762 | return -ENOMEM; | 763 | return -ENOMEM; |
@@ -841,7 +842,7 @@ int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data) | |||
841 | } | 842 | } |
842 | BUG_ON(lr->dead_node != dlm->reco.dead_node); | 843 | BUG_ON(lr->dead_node != dlm->reco.dead_node); |
843 | 844 | ||
844 | item = kcalloc(1, sizeof(*item), GFP_NOFS); | 845 | item = kzalloc(sizeof(*item), GFP_NOFS); |
845 | if (!item) { | 846 | if (!item) { |
846 | dlm_put(dlm); | 847 | dlm_put(dlm); |
847 | return -ENOMEM; | 848 | return -ENOMEM; |
@@ -1322,7 +1323,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1322 | 1323 | ||
1323 | ret = -ENOMEM; | 1324 | ret = -ENOMEM; |
1324 | buf = kmalloc(be16_to_cpu(msg->data_len), GFP_NOFS); | 1325 | buf = kmalloc(be16_to_cpu(msg->data_len), GFP_NOFS); |
1325 | item = kcalloc(1, sizeof(*item), GFP_NOFS); | 1326 | item = kzalloc(sizeof(*item), GFP_NOFS); |
1326 | if (!buf || !item) | 1327 | if (!buf || !item) |
1327 | goto leave; | 1328 | goto leave; |
1328 | 1329 | ||
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index eead48bbfac6..7d2f578b267d 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
@@ -171,15 +171,14 @@ static inline void user_dlm_grab_inode_ref(struct user_lock_res *lockres) | |||
171 | BUG(); | 171 | BUG(); |
172 | } | 172 | } |
173 | 173 | ||
174 | static void user_dlm_unblock_lock(void *opaque); | 174 | static void user_dlm_unblock_lock(struct work_struct *work); |
175 | 175 | ||
176 | static void __user_dlm_queue_lockres(struct user_lock_res *lockres) | 176 | static void __user_dlm_queue_lockres(struct user_lock_res *lockres) |
177 | { | 177 | { |
178 | if (!(lockres->l_flags & USER_LOCK_QUEUED)) { | 178 | if (!(lockres->l_flags & USER_LOCK_QUEUED)) { |
179 | user_dlm_grab_inode_ref(lockres); | 179 | user_dlm_grab_inode_ref(lockres); |
180 | 180 | ||
181 | INIT_WORK(&lockres->l_work, user_dlm_unblock_lock, | 181 | INIT_WORK(&lockres->l_work, user_dlm_unblock_lock); |
182 | lockres); | ||
183 | 182 | ||
184 | queue_work(user_dlm_worker, &lockres->l_work); | 183 | queue_work(user_dlm_worker, &lockres->l_work); |
185 | lockres->l_flags |= USER_LOCK_QUEUED; | 184 | lockres->l_flags |= USER_LOCK_QUEUED; |
@@ -279,10 +278,11 @@ static inline void user_dlm_drop_inode_ref(struct user_lock_res *lockres) | |||
279 | iput(inode); | 278 | iput(inode); |
280 | } | 279 | } |
281 | 280 | ||
282 | static void user_dlm_unblock_lock(void *opaque) | 281 | static void user_dlm_unblock_lock(struct work_struct *work) |
283 | { | 282 | { |
284 | int new_level, status; | 283 | int new_level, status; |
285 | struct user_lock_res *lockres = (struct user_lock_res *) opaque; | 284 | struct user_lock_res *lockres = |
285 | container_of(work, struct user_lock_res, l_work); | ||
286 | struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres); | 286 | struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres); |
287 | 287 | ||
288 | mlog(0, "processing lockres %.*s\n", lockres->l_namelen, | 288 | mlog(0, "processing lockres %.*s\n", lockres->l_namelen, |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 8801e41afe80..e335541727f9 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "dcache.h" | 49 | #include "dcache.h" |
50 | #include "dlmglue.h" | 50 | #include "dlmglue.h" |
51 | #include "extent_map.h" | 51 | #include "extent_map.h" |
52 | #include "file.h" | ||
52 | #include "heartbeat.h" | 53 | #include "heartbeat.h" |
53 | #include "inode.h" | 54 | #include "inode.h" |
54 | #include "journal.h" | 55 | #include "journal.h" |
@@ -769,7 +770,7 @@ static int ocfs2_lock_create(struct ocfs2_super *osb, | |||
769 | int dlm_flags) | 770 | int dlm_flags) |
770 | { | 771 | { |
771 | int ret = 0; | 772 | int ret = 0; |
772 | enum dlm_status status; | 773 | enum dlm_status status = DLM_NORMAL; |
773 | unsigned long flags; | 774 | unsigned long flags; |
774 | 775 | ||
775 | mlog_entry_void(); | 776 | mlog_entry_void(); |
@@ -1063,10 +1064,10 @@ static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | |||
1063 | mlog_exit_void(); | 1064 | mlog_exit_void(); |
1064 | } | 1065 | } |
1065 | 1066 | ||
1066 | int ocfs2_create_new_lock(struct ocfs2_super *osb, | 1067 | static int ocfs2_create_new_lock(struct ocfs2_super *osb, |
1067 | struct ocfs2_lock_res *lockres, | 1068 | struct ocfs2_lock_res *lockres, |
1068 | int ex, | 1069 | int ex, |
1069 | int local) | 1070 | int local) |
1070 | { | 1071 | { |
1071 | int level = ex ? LKM_EXMODE : LKM_PRMODE; | 1072 | int level = ex ? LKM_EXMODE : LKM_PRMODE; |
1072 | unsigned long flags; | 1073 | unsigned long flags; |
@@ -1137,6 +1138,7 @@ int ocfs2_rw_lock(struct inode *inode, int write) | |||
1137 | { | 1138 | { |
1138 | int status, level; | 1139 | int status, level; |
1139 | struct ocfs2_lock_res *lockres; | 1140 | struct ocfs2_lock_res *lockres; |
1141 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1140 | 1142 | ||
1141 | BUG_ON(!inode); | 1143 | BUG_ON(!inode); |
1142 | 1144 | ||
@@ -1146,6 +1148,9 @@ int ocfs2_rw_lock(struct inode *inode, int write) | |||
1146 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 1148 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
1147 | write ? "EXMODE" : "PRMODE"); | 1149 | write ? "EXMODE" : "PRMODE"); |
1148 | 1150 | ||
1151 | if (ocfs2_mount_local(osb)) | ||
1152 | return 0; | ||
1153 | |||
1149 | lockres = &OCFS2_I(inode)->ip_rw_lockres; | 1154 | lockres = &OCFS2_I(inode)->ip_rw_lockres; |
1150 | 1155 | ||
1151 | level = write ? LKM_EXMODE : LKM_PRMODE; | 1156 | level = write ? LKM_EXMODE : LKM_PRMODE; |
@@ -1163,6 +1168,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write) | |||
1163 | { | 1168 | { |
1164 | int level = write ? LKM_EXMODE : LKM_PRMODE; | 1169 | int level = write ? LKM_EXMODE : LKM_PRMODE; |
1165 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres; | 1170 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres; |
1171 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1166 | 1172 | ||
1167 | mlog_entry_void(); | 1173 | mlog_entry_void(); |
1168 | 1174 | ||
@@ -1170,7 +1176,8 @@ void ocfs2_rw_unlock(struct inode *inode, int write) | |||
1170 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 1176 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
1171 | write ? "EXMODE" : "PRMODE"); | 1177 | write ? "EXMODE" : "PRMODE"); |
1172 | 1178 | ||
1173 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); | 1179 | if (!ocfs2_mount_local(osb)) |
1180 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); | ||
1174 | 1181 | ||
1175 | mlog_exit_void(); | 1182 | mlog_exit_void(); |
1176 | } | 1183 | } |
@@ -1181,6 +1188,7 @@ int ocfs2_data_lock_full(struct inode *inode, | |||
1181 | { | 1188 | { |
1182 | int status = 0, level; | 1189 | int status = 0, level; |
1183 | struct ocfs2_lock_res *lockres; | 1190 | struct ocfs2_lock_res *lockres; |
1191 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1184 | 1192 | ||
1185 | BUG_ON(!inode); | 1193 | BUG_ON(!inode); |
1186 | 1194 | ||
@@ -1200,6 +1208,9 @@ int ocfs2_data_lock_full(struct inode *inode, | |||
1200 | goto out; | 1208 | goto out; |
1201 | } | 1209 | } |
1202 | 1210 | ||
1211 | if (ocfs2_mount_local(osb)) | ||
1212 | goto out; | ||
1213 | |||
1203 | lockres = &OCFS2_I(inode)->ip_data_lockres; | 1214 | lockres = &OCFS2_I(inode)->ip_data_lockres; |
1204 | 1215 | ||
1205 | level = write ? LKM_EXMODE : LKM_PRMODE; | 1216 | level = write ? LKM_EXMODE : LKM_PRMODE; |
@@ -1268,6 +1279,7 @@ void ocfs2_data_unlock(struct inode *inode, | |||
1268 | { | 1279 | { |
1269 | int level = write ? LKM_EXMODE : LKM_PRMODE; | 1280 | int level = write ? LKM_EXMODE : LKM_PRMODE; |
1270 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres; | 1281 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres; |
1282 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1271 | 1283 | ||
1272 | mlog_entry_void(); | 1284 | mlog_entry_void(); |
1273 | 1285 | ||
@@ -1275,7 +1287,8 @@ void ocfs2_data_unlock(struct inode *inode, | |||
1275 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 1287 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
1276 | write ? "EXMODE" : "PRMODE"); | 1288 | write ? "EXMODE" : "PRMODE"); |
1277 | 1289 | ||
1278 | if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb))) | 1290 | if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) && |
1291 | !ocfs2_mount_local(osb)) | ||
1279 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); | 1292 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); |
1280 | 1293 | ||
1281 | mlog_exit_void(); | 1294 | mlog_exit_void(); |
@@ -1466,8 +1479,9 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1466 | { | 1479 | { |
1467 | int status = 0; | 1480 | int status = 0; |
1468 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1481 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
1469 | struct ocfs2_lock_res *lockres; | 1482 | struct ocfs2_lock_res *lockres = NULL; |
1470 | struct ocfs2_dinode *fe; | 1483 | struct ocfs2_dinode *fe; |
1484 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1471 | 1485 | ||
1472 | mlog_entry_void(); | 1486 | mlog_entry_void(); |
1473 | 1487 | ||
@@ -1482,10 +1496,12 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1482 | } | 1496 | } |
1483 | spin_unlock(&oi->ip_lock); | 1497 | spin_unlock(&oi->ip_lock); |
1484 | 1498 | ||
1485 | lockres = &oi->ip_meta_lockres; | 1499 | if (!ocfs2_mount_local(osb)) { |
1500 | lockres = &oi->ip_meta_lockres; | ||
1486 | 1501 | ||
1487 | if (!ocfs2_should_refresh_lock_res(lockres)) | 1502 | if (!ocfs2_should_refresh_lock_res(lockres)) |
1488 | goto bail; | 1503 | goto bail; |
1504 | } | ||
1489 | 1505 | ||
1490 | /* This will discard any caching information we might have had | 1506 | /* This will discard any caching information we might have had |
1491 | * for the inode metadata. */ | 1507 | * for the inode metadata. */ |
@@ -1495,7 +1511,7 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1495 | * map (directories, bitmap files, etc) */ | 1511 | * map (directories, bitmap files, etc) */ |
1496 | ocfs2_extent_map_trunc(inode, 0); | 1512 | ocfs2_extent_map_trunc(inode, 0); |
1497 | 1513 | ||
1498 | if (ocfs2_meta_lvb_is_trustable(inode, lockres)) { | 1514 | if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) { |
1499 | mlog(0, "Trusting LVB on inode %llu\n", | 1515 | mlog(0, "Trusting LVB on inode %llu\n", |
1500 | (unsigned long long)oi->ip_blkno); | 1516 | (unsigned long long)oi->ip_blkno); |
1501 | ocfs2_refresh_inode_from_lvb(inode); | 1517 | ocfs2_refresh_inode_from_lvb(inode); |
@@ -1542,7 +1558,8 @@ static int ocfs2_meta_lock_update(struct inode *inode, | |||
1542 | 1558 | ||
1543 | status = 0; | 1559 | status = 0; |
1544 | bail_refresh: | 1560 | bail_refresh: |
1545 | ocfs2_complete_lock_res_refresh(lockres, status); | 1561 | if (lockres) |
1562 | ocfs2_complete_lock_res_refresh(lockres, status); | ||
1546 | bail: | 1563 | bail: |
1547 | mlog_exit(status); | 1564 | mlog_exit(status); |
1548 | return status; | 1565 | return status; |
@@ -1579,13 +1596,12 @@ static int ocfs2_assign_bh(struct inode *inode, | |||
1579 | * the result of the lock will be communicated via the callback. | 1596 | * the result of the lock will be communicated via the callback. |
1580 | */ | 1597 | */ |
1581 | int ocfs2_meta_lock_full(struct inode *inode, | 1598 | int ocfs2_meta_lock_full(struct inode *inode, |
1582 | struct ocfs2_journal_handle *handle, | ||
1583 | struct buffer_head **ret_bh, | 1599 | struct buffer_head **ret_bh, |
1584 | int ex, | 1600 | int ex, |
1585 | int arg_flags) | 1601 | int arg_flags) |
1586 | { | 1602 | { |
1587 | int status, level, dlm_flags, acquired; | 1603 | int status, level, dlm_flags, acquired; |
1588 | struct ocfs2_lock_res *lockres; | 1604 | struct ocfs2_lock_res *lockres = NULL; |
1589 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1605 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1590 | struct buffer_head *local_bh = NULL; | 1606 | struct buffer_head *local_bh = NULL; |
1591 | 1607 | ||
@@ -1607,6 +1623,9 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1607 | goto bail; | 1623 | goto bail; |
1608 | } | 1624 | } |
1609 | 1625 | ||
1626 | if (ocfs2_mount_local(osb)) | ||
1627 | goto local; | ||
1628 | |||
1610 | if (!(arg_flags & OCFS2_META_LOCK_RECOVERY)) | 1629 | if (!(arg_flags & OCFS2_META_LOCK_RECOVERY)) |
1611 | wait_event(osb->recovery_event, | 1630 | wait_event(osb->recovery_event, |
1612 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); | 1631 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); |
@@ -1636,6 +1655,7 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1636 | wait_event(osb->recovery_event, | 1655 | wait_event(osb->recovery_event, |
1637 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); | 1656 | ocfs2_node_map_is_empty(osb, &osb->recovery_map)); |
1638 | 1657 | ||
1658 | local: | ||
1639 | /* | 1659 | /* |
1640 | * We only see this flag if we're being called from | 1660 | * We only see this flag if we're being called from |
1641 | * ocfs2_read_locked_inode(). It means we're locking an inode | 1661 | * ocfs2_read_locked_inode(). It means we're locking an inode |
@@ -1644,7 +1664,8 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1644 | */ | 1664 | */ |
1645 | if (inode->i_state & I_NEW) { | 1665 | if (inode->i_state & I_NEW) { |
1646 | status = 0; | 1666 | status = 0; |
1647 | ocfs2_complete_lock_res_refresh(lockres, 0); | 1667 | if (lockres) |
1668 | ocfs2_complete_lock_res_refresh(lockres, 0); | ||
1648 | goto bail; | 1669 | goto bail; |
1649 | } | 1670 | } |
1650 | 1671 | ||
@@ -1668,12 +1689,6 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1668 | } | 1689 | } |
1669 | } | 1690 | } |
1670 | 1691 | ||
1671 | if (handle) { | ||
1672 | status = ocfs2_handle_add_lock(handle, inode); | ||
1673 | if (status < 0) | ||
1674 | mlog_errno(status); | ||
1675 | } | ||
1676 | |||
1677 | bail: | 1692 | bail: |
1678 | if (status < 0) { | 1693 | if (status < 0) { |
1679 | if (ret_bh && (*ret_bh)) { | 1694 | if (ret_bh && (*ret_bh)) { |
@@ -1713,18 +1728,16 @@ bail: | |||
1713 | * the lock inversion simply. | 1728 | * the lock inversion simply. |
1714 | */ | 1729 | */ |
1715 | int ocfs2_meta_lock_with_page(struct inode *inode, | 1730 | int ocfs2_meta_lock_with_page(struct inode *inode, |
1716 | struct ocfs2_journal_handle *handle, | ||
1717 | struct buffer_head **ret_bh, | 1731 | struct buffer_head **ret_bh, |
1718 | int ex, | 1732 | int ex, |
1719 | struct page *page) | 1733 | struct page *page) |
1720 | { | 1734 | { |
1721 | int ret; | 1735 | int ret; |
1722 | 1736 | ||
1723 | ret = ocfs2_meta_lock_full(inode, handle, ret_bh, ex, | 1737 | ret = ocfs2_meta_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK); |
1724 | OCFS2_LOCK_NONBLOCK); | ||
1725 | if (ret == -EAGAIN) { | 1738 | if (ret == -EAGAIN) { |
1726 | unlock_page(page); | 1739 | unlock_page(page); |
1727 | if (ocfs2_meta_lock(inode, handle, ret_bh, ex) == 0) | 1740 | if (ocfs2_meta_lock(inode, ret_bh, ex) == 0) |
1728 | ocfs2_meta_unlock(inode, ex); | 1741 | ocfs2_meta_unlock(inode, ex); |
1729 | ret = AOP_TRUNCATED_PAGE; | 1742 | ret = AOP_TRUNCATED_PAGE; |
1730 | } | 1743 | } |
@@ -1732,11 +1745,50 @@ int ocfs2_meta_lock_with_page(struct inode *inode, | |||
1732 | return ret; | 1745 | return ret; |
1733 | } | 1746 | } |
1734 | 1747 | ||
1748 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
1749 | struct vfsmount *vfsmnt, | ||
1750 | int *level) | ||
1751 | { | ||
1752 | int ret; | ||
1753 | |||
1754 | mlog_entry_void(); | ||
1755 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
1756 | if (ret < 0) { | ||
1757 | mlog_errno(ret); | ||
1758 | return ret; | ||
1759 | } | ||
1760 | |||
1761 | /* | ||
1762 | * If we should update atime, we will get EX lock, | ||
1763 | * otherwise we just get PR lock. | ||
1764 | */ | ||
1765 | if (ocfs2_should_update_atime(inode, vfsmnt)) { | ||
1766 | struct buffer_head *bh = NULL; | ||
1767 | |||
1768 | ocfs2_meta_unlock(inode, 0); | ||
1769 | ret = ocfs2_meta_lock(inode, &bh, 1); | ||
1770 | if (ret < 0) { | ||
1771 | mlog_errno(ret); | ||
1772 | return ret; | ||
1773 | } | ||
1774 | *level = 1; | ||
1775 | if (ocfs2_should_update_atime(inode, vfsmnt)) | ||
1776 | ocfs2_update_inode_atime(inode, bh); | ||
1777 | if (bh) | ||
1778 | brelse(bh); | ||
1779 | } else | ||
1780 | *level = 0; | ||
1781 | |||
1782 | mlog_exit(ret); | ||
1783 | return ret; | ||
1784 | } | ||
1785 | |||
1735 | void ocfs2_meta_unlock(struct inode *inode, | 1786 | void ocfs2_meta_unlock(struct inode *inode, |
1736 | int ex) | 1787 | int ex) |
1737 | { | 1788 | { |
1738 | int level = ex ? LKM_EXMODE : LKM_PRMODE; | 1789 | int level = ex ? LKM_EXMODE : LKM_PRMODE; |
1739 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres; | 1790 | struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres; |
1791 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1740 | 1792 | ||
1741 | mlog_entry_void(); | 1793 | mlog_entry_void(); |
1742 | 1794 | ||
@@ -1744,7 +1796,8 @@ void ocfs2_meta_unlock(struct inode *inode, | |||
1744 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 1796 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
1745 | ex ? "EXMODE" : "PRMODE"); | 1797 | ex ? "EXMODE" : "PRMODE"); |
1746 | 1798 | ||
1747 | if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb))) | 1799 | if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) && |
1800 | !ocfs2_mount_local(osb)) | ||
1748 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); | 1801 | ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level); |
1749 | 1802 | ||
1750 | mlog_exit_void(); | 1803 | mlog_exit_void(); |
@@ -1753,7 +1806,7 @@ void ocfs2_meta_unlock(struct inode *inode, | |||
1753 | int ocfs2_super_lock(struct ocfs2_super *osb, | 1806 | int ocfs2_super_lock(struct ocfs2_super *osb, |
1754 | int ex) | 1807 | int ex) |
1755 | { | 1808 | { |
1756 | int status; | 1809 | int status = 0; |
1757 | int level = ex ? LKM_EXMODE : LKM_PRMODE; | 1810 | int level = ex ? LKM_EXMODE : LKM_PRMODE; |
1758 | struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; | 1811 | struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; |
1759 | struct buffer_head *bh; | 1812 | struct buffer_head *bh; |
@@ -1764,6 +1817,9 @@ int ocfs2_super_lock(struct ocfs2_super *osb, | |||
1764 | if (ocfs2_is_hard_readonly(osb)) | 1817 | if (ocfs2_is_hard_readonly(osb)) |
1765 | return -EROFS; | 1818 | return -EROFS; |
1766 | 1819 | ||
1820 | if (ocfs2_mount_local(osb)) | ||
1821 | goto bail; | ||
1822 | |||
1767 | status = ocfs2_cluster_lock(osb, lockres, level, 0, 0); | 1823 | status = ocfs2_cluster_lock(osb, lockres, level, 0, 0); |
1768 | if (status < 0) { | 1824 | if (status < 0) { |
1769 | mlog_errno(status); | 1825 | mlog_errno(status); |
@@ -1802,7 +1858,8 @@ void ocfs2_super_unlock(struct ocfs2_super *osb, | |||
1802 | int level = ex ? LKM_EXMODE : LKM_PRMODE; | 1858 | int level = ex ? LKM_EXMODE : LKM_PRMODE; |
1803 | struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; | 1859 | struct ocfs2_lock_res *lockres = &osb->osb_super_lockres; |
1804 | 1860 | ||
1805 | ocfs2_cluster_unlock(osb, lockres, level); | 1861 | if (!ocfs2_mount_local(osb)) |
1862 | ocfs2_cluster_unlock(osb, lockres, level); | ||
1806 | } | 1863 | } |
1807 | 1864 | ||
1808 | int ocfs2_rename_lock(struct ocfs2_super *osb) | 1865 | int ocfs2_rename_lock(struct ocfs2_super *osb) |
@@ -1813,6 +1870,9 @@ int ocfs2_rename_lock(struct ocfs2_super *osb) | |||
1813 | if (ocfs2_is_hard_readonly(osb)) | 1870 | if (ocfs2_is_hard_readonly(osb)) |
1814 | return -EROFS; | 1871 | return -EROFS; |
1815 | 1872 | ||
1873 | if (ocfs2_mount_local(osb)) | ||
1874 | return 0; | ||
1875 | |||
1816 | status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0); | 1876 | status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0); |
1817 | if (status < 0) | 1877 | if (status < 0) |
1818 | mlog_errno(status); | 1878 | mlog_errno(status); |
@@ -1824,7 +1884,8 @@ void ocfs2_rename_unlock(struct ocfs2_super *osb) | |||
1824 | { | 1884 | { |
1825 | struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres; | 1885 | struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres; |
1826 | 1886 | ||
1827 | ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE); | 1887 | if (!ocfs2_mount_local(osb)) |
1888 | ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE); | ||
1828 | } | 1889 | } |
1829 | 1890 | ||
1830 | int ocfs2_dentry_lock(struct dentry *dentry, int ex) | 1891 | int ocfs2_dentry_lock(struct dentry *dentry, int ex) |
@@ -1839,6 +1900,9 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex) | |||
1839 | if (ocfs2_is_hard_readonly(osb)) | 1900 | if (ocfs2_is_hard_readonly(osb)) |
1840 | return -EROFS; | 1901 | return -EROFS; |
1841 | 1902 | ||
1903 | if (ocfs2_mount_local(osb)) | ||
1904 | return 0; | ||
1905 | |||
1842 | ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0); | 1906 | ret = ocfs2_cluster_lock(osb, &dl->dl_lockres, level, 0, 0); |
1843 | if (ret < 0) | 1907 | if (ret < 0) |
1844 | mlog_errno(ret); | 1908 | mlog_errno(ret); |
@@ -1852,7 +1916,8 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex) | |||
1852 | struct ocfs2_dentry_lock *dl = dentry->d_fsdata; | 1916 | struct ocfs2_dentry_lock *dl = dentry->d_fsdata; |
1853 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); | 1917 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); |
1854 | 1918 | ||
1855 | ocfs2_cluster_unlock(osb, &dl->dl_lockres, level); | 1919 | if (!ocfs2_mount_local(osb)) |
1920 | ocfs2_cluster_unlock(osb, &dl->dl_lockres, level); | ||
1856 | } | 1921 | } |
1857 | 1922 | ||
1858 | /* Reference counting of the dlm debug structure. We want this because | 1923 | /* Reference counting of the dlm debug structure. We want this because |
@@ -2115,12 +2180,15 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb) | |||
2115 | 2180 | ||
2116 | int ocfs2_dlm_init(struct ocfs2_super *osb) | 2181 | int ocfs2_dlm_init(struct ocfs2_super *osb) |
2117 | { | 2182 | { |
2118 | int status; | 2183 | int status = 0; |
2119 | u32 dlm_key; | 2184 | u32 dlm_key; |
2120 | struct dlm_ctxt *dlm; | 2185 | struct dlm_ctxt *dlm = NULL; |
2121 | 2186 | ||
2122 | mlog_entry_void(); | 2187 | mlog_entry_void(); |
2123 | 2188 | ||
2189 | if (ocfs2_mount_local(osb)) | ||
2190 | goto local; | ||
2191 | |||
2124 | status = ocfs2_dlm_init_debug(osb); | 2192 | status = ocfs2_dlm_init_debug(osb); |
2125 | if (status < 0) { | 2193 | if (status < 0) { |
2126 | mlog_errno(status); | 2194 | mlog_errno(status); |
@@ -2148,11 +2216,12 @@ int ocfs2_dlm_init(struct ocfs2_super *osb) | |||
2148 | goto bail; | 2216 | goto bail; |
2149 | } | 2217 | } |
2150 | 2218 | ||
2219 | dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb); | ||
2220 | |||
2221 | local: | ||
2151 | ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb); | 2222 | ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb); |
2152 | ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb); | 2223 | ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb); |
2153 | 2224 | ||
2154 | dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb); | ||
2155 | |||
2156 | osb->dlm = dlm; | 2225 | osb->dlm = dlm; |
2157 | 2226 | ||
2158 | status = 0; | 2227 | status = 0; |
@@ -2649,6 +2718,15 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | |||
2649 | inode = ocfs2_lock_res_inode(lockres); | 2718 | inode = ocfs2_lock_res_inode(lockres); |
2650 | mapping = inode->i_mapping; | 2719 | mapping = inode->i_mapping; |
2651 | 2720 | ||
2721 | /* | ||
2722 | * We need this before the filemap_fdatawrite() so that it can | ||
2723 | * transfer the dirty bit from the PTE to the | ||
2724 | * page. Unfortunately this means that even for EX->PR | ||
2725 | * downconverts, we'll lose our mappings and have to build | ||
2726 | * them up again. | ||
2727 | */ | ||
2728 | unmap_mapping_range(mapping, 0, 0, 0); | ||
2729 | |||
2652 | if (filemap_fdatawrite(mapping)) { | 2730 | if (filemap_fdatawrite(mapping)) { |
2653 | mlog(ML_ERROR, "Could not sync inode %llu for downconvert!", | 2731 | mlog(ML_ERROR, "Could not sync inode %llu for downconvert!", |
2654 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 2732 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
@@ -2656,7 +2734,6 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | |||
2656 | sync_mapping_buffers(mapping); | 2734 | sync_mapping_buffers(mapping); |
2657 | if (blocking == LKM_EXMODE) { | 2735 | if (blocking == LKM_EXMODE) { |
2658 | truncate_inode_pages(mapping, 0); | 2736 | truncate_inode_pages(mapping, 0); |
2659 | unmap_mapping_range(mapping, 0, 0, 0); | ||
2660 | } else { | 2737 | } else { |
2661 | /* We only need to wait on the I/O if we're not also | 2738 | /* We only need to wait on the I/O if we're not also |
2662 | * truncating pages because truncate_inode_pages waits | 2739 | * truncating pages because truncate_inode_pages waits |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 4a2769387229..c343fca68cf1 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -68,8 +68,6 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl, | |||
68 | u64 parent, struct inode *inode); | 68 | u64 parent, struct inode *inode); |
69 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res); | 69 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res); |
70 | int ocfs2_create_new_inode_locks(struct inode *inode); | 70 | int ocfs2_create_new_inode_locks(struct inode *inode); |
71 | int ocfs2_create_new_lock(struct ocfs2_super *osb, | ||
72 | struct ocfs2_lock_res *lockres, int ex, int local); | ||
73 | int ocfs2_drop_inode_locks(struct inode *inode); | 71 | int ocfs2_drop_inode_locks(struct inode *inode); |
74 | int ocfs2_data_lock_full(struct inode *inode, | 72 | int ocfs2_data_lock_full(struct inode *inode, |
75 | int write, | 73 | int write, |
@@ -82,19 +80,20 @@ void ocfs2_data_unlock(struct inode *inode, | |||
82 | int write); | 80 | int write); |
83 | int ocfs2_rw_lock(struct inode *inode, int write); | 81 | int ocfs2_rw_lock(struct inode *inode, int write); |
84 | void ocfs2_rw_unlock(struct inode *inode, int write); | 82 | void ocfs2_rw_unlock(struct inode *inode, int write); |
83 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
84 | struct vfsmount *vfsmnt, | ||
85 | int *level); | ||
85 | int ocfs2_meta_lock_full(struct inode *inode, | 86 | int ocfs2_meta_lock_full(struct inode *inode, |
86 | struct ocfs2_journal_handle *handle, | ||
87 | struct buffer_head **ret_bh, | 87 | struct buffer_head **ret_bh, |
88 | int ex, | 88 | int ex, |
89 | int arg_flags); | 89 | int arg_flags); |
90 | int ocfs2_meta_lock_with_page(struct inode *inode, | 90 | int ocfs2_meta_lock_with_page(struct inode *inode, |
91 | struct ocfs2_journal_handle *handle, | ||
92 | struct buffer_head **ret_bh, | 91 | struct buffer_head **ret_bh, |
93 | int ex, | 92 | int ex, |
94 | struct page *page); | 93 | struct page *page); |
95 | /* 99% of the time we don't want to supply any additional flags -- | 94 | /* 99% of the time we don't want to supply any additional flags -- |
96 | * those are for very specific cases only. */ | 95 | * those are for very specific cases only. */ |
97 | #define ocfs2_meta_lock(i, h, b, e) ocfs2_meta_lock_full(i, h, b, e, 0) | 96 | #define ocfs2_meta_lock(i, b, e) ocfs2_meta_lock_full(i, b, e, 0) |
98 | void ocfs2_meta_unlock(struct inode *inode, | 97 | void ocfs2_meta_unlock(struct inode *inode, |
99 | int ex); | 98 | int ex); |
100 | int ocfs2_super_lock(struct ocfs2_super *osb, | 99 | int ocfs2_super_lock(struct ocfs2_super *osb, |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index fb91089a60a7..06be6e774cf9 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -100,7 +100,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) | |||
100 | mlog(0, "find parent of directory %llu\n", | 100 | mlog(0, "find parent of directory %llu\n", |
101 | (unsigned long long)OCFS2_I(dir)->ip_blkno); | 101 | (unsigned long long)OCFS2_I(dir)->ip_blkno); |
102 | 102 | ||
103 | status = ocfs2_meta_lock(dir, NULL, NULL, 0); | 103 | status = ocfs2_meta_lock(dir, NULL, 0); |
104 | if (status < 0) { | 104 | if (status < 0) { |
105 | if (status != -ENOENT) | 105 | if (status != -ENOENT) |
106 | mlog_errno(status); | 106 | mlog_errno(status); |
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index fcd4475d1f89..80ac69f11d9f 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
@@ -61,7 +61,7 @@ struct ocfs2_em_insert_context { | |||
61 | struct ocfs2_extent_map_entry *right_ent; | 61 | struct ocfs2_extent_map_entry *right_ent; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static kmem_cache_t *ocfs2_em_ent_cachep = NULL; | 64 | static struct kmem_cache *ocfs2_em_ent_cachep = NULL; |
65 | 65 | ||
66 | 66 | ||
67 | static struct ocfs2_extent_map_entry * | 67 | static struct ocfs2_extent_map_entry * |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 1be74c4e7814..10953a508f2f 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
32 | #include <linux/uio.h> | 32 | #include <linux/uio.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/pipe_fs_i.h> | ||
35 | #include <linux/mount.h> | ||
34 | 36 | ||
35 | #define MLOG_MASK_PREFIX ML_INODE | 37 | #define MLOG_MASK_PREFIX ML_INODE |
36 | #include <cluster/masklog.h> | 38 | #include <cluster/masklog.h> |
@@ -66,7 +68,7 @@ static int ocfs2_file_open(struct inode *inode, struct file *file) | |||
66 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 68 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
67 | 69 | ||
68 | mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, | 70 | mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, |
69 | file->f_dentry->d_name.len, file->f_dentry->d_name.name); | 71 | file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name); |
70 | 72 | ||
71 | spin_lock(&oi->ip_lock); | 73 | spin_lock(&oi->ip_lock); |
72 | 74 | ||
@@ -96,8 +98,8 @@ static int ocfs2_file_release(struct inode *inode, struct file *file) | |||
96 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 98 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
97 | 99 | ||
98 | mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, | 100 | mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, |
99 | file->f_dentry->d_name.len, | 101 | file->f_path.dentry->d_name.len, |
100 | file->f_dentry->d_name.name); | 102 | file->f_path.dentry->d_name.name); |
101 | 103 | ||
102 | spin_lock(&oi->ip_lock); | 104 | spin_lock(&oi->ip_lock); |
103 | if (!--oi->ip_open_count) | 105 | if (!--oi->ip_open_count) |
@@ -134,7 +136,77 @@ bail: | |||
134 | return (err < 0) ? -EIO : 0; | 136 | return (err < 0) ? -EIO : 0; |
135 | } | 137 | } |
136 | 138 | ||
137 | int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, | 139 | int ocfs2_should_update_atime(struct inode *inode, |
140 | struct vfsmount *vfsmnt) | ||
141 | { | ||
142 | struct timespec now; | ||
143 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
144 | |||
145 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
146 | return 0; | ||
147 | |||
148 | if ((inode->i_flags & S_NOATIME) || | ||
149 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
150 | return 0; | ||
151 | |||
152 | /* | ||
153 | * We can be called with no vfsmnt structure - NFSD will | ||
154 | * sometimes do this. | ||
155 | * | ||
156 | * Note that our action here is different than touch_atime() - | ||
157 | * if we can't tell whether this is a noatime mount, then we | ||
158 | * don't know whether to trust the value of s_atime_quantum. | ||
159 | */ | ||
160 | if (vfsmnt == NULL) | ||
161 | return 0; | ||
162 | |||
163 | if ((vfsmnt->mnt_flags & MNT_NOATIME) || | ||
164 | ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
165 | return 0; | ||
166 | |||
167 | if (vfsmnt->mnt_flags & MNT_RELATIME) { | ||
168 | if ((timespec_compare(&inode->i_atime, &inode->i_mtime) <= 0) || | ||
169 | (timespec_compare(&inode->i_atime, &inode->i_ctime) <= 0)) | ||
170 | return 1; | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | now = CURRENT_TIME; | ||
176 | if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum)) | ||
177 | return 0; | ||
178 | else | ||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | int ocfs2_update_inode_atime(struct inode *inode, | ||
183 | struct buffer_head *bh) | ||
184 | { | ||
185 | int ret; | ||
186 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
187 | handle_t *handle; | ||
188 | |||
189 | mlog_entry_void(); | ||
190 | |||
191 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
192 | if (handle == NULL) { | ||
193 | ret = -ENOMEM; | ||
194 | mlog_errno(ret); | ||
195 | goto out; | ||
196 | } | ||
197 | |||
198 | inode->i_atime = CURRENT_TIME; | ||
199 | ret = ocfs2_mark_inode_dirty(handle, inode, bh); | ||
200 | if (ret < 0) | ||
201 | mlog_errno(ret); | ||
202 | |||
203 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | ||
204 | out: | ||
205 | mlog_exit(ret); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | int ocfs2_set_inode_size(handle_t *handle, | ||
138 | struct inode *inode, | 210 | struct inode *inode, |
139 | struct buffer_head *fe_bh, | 211 | struct buffer_head *fe_bh, |
140 | u64 new_i_size) | 212 | u64 new_i_size) |
@@ -163,10 +235,9 @@ static int ocfs2_simple_size_update(struct inode *inode, | |||
163 | { | 235 | { |
164 | int ret; | 236 | int ret; |
165 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 237 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
166 | struct ocfs2_journal_handle *handle = NULL; | 238 | handle_t *handle = NULL; |
167 | 239 | ||
168 | handle = ocfs2_start_trans(osb, NULL, | 240 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
169 | OCFS2_INODE_UPDATE_CREDITS); | ||
170 | if (handle == NULL) { | 241 | if (handle == NULL) { |
171 | ret = -ENOMEM; | 242 | ret = -ENOMEM; |
172 | mlog_errno(ret); | 243 | mlog_errno(ret); |
@@ -178,7 +249,7 @@ static int ocfs2_simple_size_update(struct inode *inode, | |||
178 | if (ret < 0) | 249 | if (ret < 0) |
179 | mlog_errno(ret); | 250 | mlog_errno(ret); |
180 | 251 | ||
181 | ocfs2_commit_trans(handle); | 252 | ocfs2_commit_trans(osb, handle); |
182 | out: | 253 | out: |
183 | return ret; | 254 | return ret; |
184 | } | 255 | } |
@@ -189,14 +260,14 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, | |||
189 | u64 new_i_size) | 260 | u64 new_i_size) |
190 | { | 261 | { |
191 | int status; | 262 | int status; |
192 | struct ocfs2_journal_handle *handle; | 263 | handle_t *handle; |
193 | 264 | ||
194 | mlog_entry_void(); | 265 | mlog_entry_void(); |
195 | 266 | ||
196 | /* TODO: This needs to actually orphan the inode in this | 267 | /* TODO: This needs to actually orphan the inode in this |
197 | * transaction. */ | 268 | * transaction. */ |
198 | 269 | ||
199 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 270 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
200 | if (IS_ERR(handle)) { | 271 | if (IS_ERR(handle)) { |
201 | status = PTR_ERR(handle); | 272 | status = PTR_ERR(handle); |
202 | mlog_errno(status); | 273 | mlog_errno(status); |
@@ -207,7 +278,7 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, | |||
207 | if (status < 0) | 278 | if (status < 0) |
208 | mlog_errno(status); | 279 | mlog_errno(status); |
209 | 280 | ||
210 | ocfs2_commit_trans(handle); | 281 | ocfs2_commit_trans(osb, handle); |
211 | out: | 282 | out: |
212 | mlog_exit(status); | 283 | mlog_exit(status); |
213 | return status; | 284 | return status; |
@@ -328,7 +399,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
328 | struct inode *inode, | 399 | struct inode *inode, |
329 | u32 clusters_to_add, | 400 | u32 clusters_to_add, |
330 | struct buffer_head *fe_bh, | 401 | struct buffer_head *fe_bh, |
331 | struct ocfs2_journal_handle *handle, | 402 | handle_t *handle, |
332 | struct ocfs2_alloc_context *data_ac, | 403 | struct ocfs2_alloc_context *data_ac, |
333 | struct ocfs2_alloc_context *meta_ac, | 404 | struct ocfs2_alloc_context *meta_ac, |
334 | enum ocfs2_alloc_restarted *reason_ret) | 405 | enum ocfs2_alloc_restarted *reason_ret) |
@@ -433,7 +504,7 @@ static int ocfs2_extend_allocation(struct inode *inode, | |||
433 | u32 prev_clusters; | 504 | u32 prev_clusters; |
434 | struct buffer_head *bh = NULL; | 505 | struct buffer_head *bh = NULL; |
435 | struct ocfs2_dinode *fe = NULL; | 506 | struct ocfs2_dinode *fe = NULL; |
436 | struct ocfs2_journal_handle *handle = NULL; | 507 | handle_t *handle = NULL; |
437 | struct ocfs2_alloc_context *data_ac = NULL; | 508 | struct ocfs2_alloc_context *data_ac = NULL; |
438 | struct ocfs2_alloc_context *meta_ac = NULL; | 509 | struct ocfs2_alloc_context *meta_ac = NULL; |
439 | enum ocfs2_alloc_restarted why; | 510 | enum ocfs2_alloc_restarted why; |
@@ -463,13 +534,6 @@ restart_all: | |||
463 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), | 534 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), |
464 | fe->i_clusters, clusters_to_add); | 535 | fe->i_clusters, clusters_to_add); |
465 | 536 | ||
466 | handle = ocfs2_alloc_handle(osb); | ||
467 | if (handle == NULL) { | ||
468 | status = -ENOMEM; | ||
469 | mlog_errno(status); | ||
470 | goto leave; | ||
471 | } | ||
472 | |||
473 | num_free_extents = ocfs2_num_free_extents(osb, | 537 | num_free_extents = ocfs2_num_free_extents(osb, |
474 | inode, | 538 | inode, |
475 | fe); | 539 | fe); |
@@ -480,10 +544,7 @@ restart_all: | |||
480 | } | 544 | } |
481 | 545 | ||
482 | if (!num_free_extents) { | 546 | if (!num_free_extents) { |
483 | status = ocfs2_reserve_new_metadata(osb, | 547 | status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); |
484 | handle, | ||
485 | fe, | ||
486 | &meta_ac); | ||
487 | if (status < 0) { | 548 | if (status < 0) { |
488 | if (status != -ENOSPC) | 549 | if (status != -ENOSPC) |
489 | mlog_errno(status); | 550 | mlog_errno(status); |
@@ -491,10 +552,7 @@ restart_all: | |||
491 | } | 552 | } |
492 | } | 553 | } |
493 | 554 | ||
494 | status = ocfs2_reserve_clusters(osb, | 555 | status = ocfs2_reserve_clusters(osb, clusters_to_add, &data_ac); |
495 | handle, | ||
496 | clusters_to_add, | ||
497 | &data_ac); | ||
498 | if (status < 0) { | 556 | if (status < 0) { |
499 | if (status != -ENOSPC) | 557 | if (status != -ENOSPC) |
500 | mlog_errno(status); | 558 | mlog_errno(status); |
@@ -509,7 +567,7 @@ restart_all: | |||
509 | drop_alloc_sem = 1; | 567 | drop_alloc_sem = 1; |
510 | 568 | ||
511 | credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); | 569 | credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); |
512 | handle = ocfs2_start_trans(osb, handle, credits); | 570 | handle = ocfs2_start_trans(osb, credits); |
513 | if (IS_ERR(handle)) { | 571 | if (IS_ERR(handle)) { |
514 | status = PTR_ERR(handle); | 572 | status = PTR_ERR(handle); |
515 | handle = NULL; | 573 | handle = NULL; |
@@ -589,7 +647,7 @@ leave: | |||
589 | drop_alloc_sem = 0; | 647 | drop_alloc_sem = 0; |
590 | } | 648 | } |
591 | if (handle) { | 649 | if (handle) { |
592 | ocfs2_commit_trans(handle); | 650 | ocfs2_commit_trans(osb, handle); |
593 | handle = NULL; | 651 | handle = NULL; |
594 | } | 652 | } |
595 | if (data_ac) { | 653 | if (data_ac) { |
@@ -624,7 +682,7 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
624 | struct page *page; | 682 | struct page *page; |
625 | unsigned long index; | 683 | unsigned long index; |
626 | unsigned int offset; | 684 | unsigned int offset; |
627 | struct ocfs2_journal_handle *handle = NULL; | 685 | handle_t *handle = NULL; |
628 | int ret; | 686 | int ret; |
629 | 687 | ||
630 | offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ | 688 | offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ |
@@ -668,7 +726,7 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
668 | ret = 0; | 726 | ret = 0; |
669 | 727 | ||
670 | if (handle) | 728 | if (handle) |
671 | ocfs2_commit_trans(handle); | 729 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
672 | out_unlock: | 730 | out_unlock: |
673 | unlock_page(page); | 731 | unlock_page(page); |
674 | page_cache_release(page); | 732 | page_cache_release(page); |
@@ -789,7 +847,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
789 | struct super_block *sb = inode->i_sb; | 847 | struct super_block *sb = inode->i_sb; |
790 | struct ocfs2_super *osb = OCFS2_SB(sb); | 848 | struct ocfs2_super *osb = OCFS2_SB(sb); |
791 | struct buffer_head *bh = NULL; | 849 | struct buffer_head *bh = NULL; |
792 | struct ocfs2_journal_handle *handle = NULL; | 850 | handle_t *handle = NULL; |
793 | 851 | ||
794 | mlog_entry("(0x%p, '%.*s')\n", dentry, | 852 | mlog_entry("(0x%p, '%.*s')\n", dentry, |
795 | dentry->d_name.len, dentry->d_name.name); | 853 | dentry->d_name.len, dentry->d_name.name); |
@@ -825,7 +883,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
825 | } | 883 | } |
826 | } | 884 | } |
827 | 885 | ||
828 | status = ocfs2_meta_lock(inode, NULL, &bh, 1); | 886 | status = ocfs2_meta_lock(inode, &bh, 1); |
829 | if (status < 0) { | 887 | if (status < 0) { |
830 | if (status != -ENOENT) | 888 | if (status != -ENOENT) |
831 | mlog_errno(status); | 889 | mlog_errno(status); |
@@ -845,7 +903,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
845 | } | 903 | } |
846 | } | 904 | } |
847 | 905 | ||
848 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 906 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
849 | if (IS_ERR(handle)) { | 907 | if (IS_ERR(handle)) { |
850 | status = PTR_ERR(handle); | 908 | status = PTR_ERR(handle); |
851 | mlog_errno(status); | 909 | mlog_errno(status); |
@@ -863,7 +921,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
863 | mlog_errno(status); | 921 | mlog_errno(status); |
864 | 922 | ||
865 | bail_commit: | 923 | bail_commit: |
866 | ocfs2_commit_trans(handle); | 924 | ocfs2_commit_trans(osb, handle); |
867 | bail_unlock: | 925 | bail_unlock: |
868 | ocfs2_meta_unlock(inode, 1); | 926 | ocfs2_meta_unlock(inode, 1); |
869 | bail_unlock_rw: | 927 | bail_unlock_rw: |
@@ -906,19 +964,39 @@ bail: | |||
906 | return err; | 964 | return err; |
907 | } | 965 | } |
908 | 966 | ||
967 | int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
968 | { | ||
969 | int ret; | ||
970 | |||
971 | mlog_entry_void(); | ||
972 | |||
973 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
974 | if (ret) { | ||
975 | mlog_errno(ret); | ||
976 | goto out; | ||
977 | } | ||
978 | |||
979 | ret = generic_permission(inode, mask, NULL); | ||
980 | |||
981 | ocfs2_meta_unlock(inode, 0); | ||
982 | out: | ||
983 | mlog_exit(ret); | ||
984 | return ret; | ||
985 | } | ||
986 | |||
909 | static int ocfs2_write_remove_suid(struct inode *inode) | 987 | static int ocfs2_write_remove_suid(struct inode *inode) |
910 | { | 988 | { |
911 | int ret; | 989 | int ret; |
912 | struct buffer_head *bh = NULL; | 990 | struct buffer_head *bh = NULL; |
913 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 991 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
914 | struct ocfs2_journal_handle *handle; | 992 | handle_t *handle; |
915 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 993 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
916 | struct ocfs2_dinode *di; | 994 | struct ocfs2_dinode *di; |
917 | 995 | ||
918 | mlog_entry("(Inode %llu, mode 0%o)\n", | 996 | mlog_entry("(Inode %llu, mode 0%o)\n", |
919 | (unsigned long long)oi->ip_blkno, inode->i_mode); | 997 | (unsigned long long)oi->ip_blkno, inode->i_mode); |
920 | 998 | ||
921 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 999 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
922 | if (handle == NULL) { | 1000 | if (handle == NULL) { |
923 | ret = -ENOMEM; | 1001 | ret = -ENOMEM; |
924 | mlog_errno(ret); | 1002 | mlog_errno(ret); |
@@ -951,75 +1029,29 @@ static int ocfs2_write_remove_suid(struct inode *inode) | |||
951 | out_bh: | 1029 | out_bh: |
952 | brelse(bh); | 1030 | brelse(bh); |
953 | out_trans: | 1031 | out_trans: |
954 | ocfs2_commit_trans(handle); | 1032 | ocfs2_commit_trans(osb, handle); |
955 | out: | 1033 | out: |
956 | mlog_exit(ret); | 1034 | mlog_exit(ret); |
957 | return ret; | 1035 | return ret; |
958 | } | 1036 | } |
959 | 1037 | ||
960 | static inline int ocfs2_write_should_remove_suid(struct inode *inode) | 1038 | static int ocfs2_prepare_inode_for_write(struct dentry *dentry, |
961 | { | 1039 | loff_t *ppos, |
962 | mode_t mode = inode->i_mode; | 1040 | size_t count, |
963 | 1041 | int appending) | |
964 | if (!capable(CAP_FSETID)) { | ||
965 | if (unlikely(mode & S_ISUID)) | ||
966 | return 1; | ||
967 | |||
968 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) | ||
969 | return 1; | ||
970 | } | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | ||
975 | const struct iovec *iov, | ||
976 | unsigned long nr_segs, | ||
977 | loff_t pos) | ||
978 | { | 1042 | { |
979 | int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; | 1043 | int ret = 0, meta_level = appending; |
1044 | struct inode *inode = dentry->d_inode; | ||
980 | u32 clusters; | 1045 | u32 clusters; |
981 | struct file *filp = iocb->ki_filp; | ||
982 | struct inode *inode = filp->f_dentry->d_inode; | ||
983 | loff_t newsize, saved_pos; | 1046 | loff_t newsize, saved_pos; |
984 | 1047 | ||
985 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, | ||
986 | (unsigned int)nr_segs, | ||
987 | filp->f_dentry->d_name.len, | ||
988 | filp->f_dentry->d_name.name); | ||
989 | |||
990 | /* happy write of zero bytes */ | ||
991 | if (iocb->ki_left == 0) | ||
992 | return 0; | ||
993 | |||
994 | if (!inode) { | ||
995 | mlog(0, "bad inode\n"); | ||
996 | return -EIO; | ||
997 | } | ||
998 | |||
999 | mutex_lock(&inode->i_mutex); | ||
1000 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | ||
1001 | if (filp->f_flags & O_DIRECT) { | ||
1002 | have_alloc_sem = 1; | ||
1003 | down_read(&inode->i_alloc_sem); | ||
1004 | } | ||
1005 | |||
1006 | /* concurrent O_DIRECT writes are allowed */ | ||
1007 | rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1; | ||
1008 | ret = ocfs2_rw_lock(inode, rw_level); | ||
1009 | if (ret < 0) { | ||
1010 | rw_level = -1; | ||
1011 | mlog_errno(ret); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | |||
1015 | /* | 1048 | /* |
1016 | * We sample i_size under a read level meta lock to see if our write | 1049 | * We sample i_size under a read level meta lock to see if our write |
1017 | * is extending the file, if it is we back off and get a write level | 1050 | * is extending the file, if it is we back off and get a write level |
1018 | * meta lock. | 1051 | * meta lock. |
1019 | */ | 1052 | */ |
1020 | meta_level = (filp->f_flags & O_APPEND) ? 1 : 0; | ||
1021 | for(;;) { | 1053 | for(;;) { |
1022 | ret = ocfs2_meta_lock(inode, NULL, NULL, meta_level); | 1054 | ret = ocfs2_meta_lock(inode, NULL, meta_level); |
1023 | if (ret < 0) { | 1055 | if (ret < 0) { |
1024 | meta_level = -1; | 1056 | meta_level = -1; |
1025 | mlog_errno(ret); | 1057 | mlog_errno(ret); |
@@ -1035,7 +1067,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1035 | * inode. There's also the dinode i_size state which | 1067 | * inode. There's also the dinode i_size state which |
1036 | * can be lost via setattr during extending writes (we | 1068 | * can be lost via setattr during extending writes (we |
1037 | * set inode->i_size at the end of a write. */ | 1069 | * set inode->i_size at the end of a write. */ |
1038 | if (ocfs2_write_should_remove_suid(inode)) { | 1070 | if (should_remove_suid(dentry)) { |
1039 | if (meta_level == 0) { | 1071 | if (meta_level == 0) { |
1040 | ocfs2_meta_unlock(inode, meta_level); | 1072 | ocfs2_meta_unlock(inode, meta_level); |
1041 | meta_level = 1; | 1073 | meta_level = 1; |
@@ -1045,19 +1077,19 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1045 | ret = ocfs2_write_remove_suid(inode); | 1077 | ret = ocfs2_write_remove_suid(inode); |
1046 | if (ret < 0) { | 1078 | if (ret < 0) { |
1047 | mlog_errno(ret); | 1079 | mlog_errno(ret); |
1048 | goto out; | 1080 | goto out_unlock; |
1049 | } | 1081 | } |
1050 | } | 1082 | } |
1051 | 1083 | ||
1052 | /* work on a copy of ppos until we're sure that we won't have | 1084 | /* work on a copy of ppos until we're sure that we won't have |
1053 | * to recalculate it due to relocking. */ | 1085 | * to recalculate it due to relocking. */ |
1054 | if (filp->f_flags & O_APPEND) { | 1086 | if (appending) { |
1055 | saved_pos = i_size_read(inode); | 1087 | saved_pos = i_size_read(inode); |
1056 | mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); | 1088 | mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); |
1057 | } else { | 1089 | } else { |
1058 | saved_pos = iocb->ki_pos; | 1090 | saved_pos = *ppos; |
1059 | } | 1091 | } |
1060 | newsize = iocb->ki_left + saved_pos; | 1092 | newsize = count + saved_pos; |
1061 | 1093 | ||
1062 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", | 1094 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", |
1063 | (long long) saved_pos, (long long) newsize, | 1095 | (long long) saved_pos, (long long) newsize, |
@@ -1090,19 +1122,66 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1090 | if (!clusters) | 1122 | if (!clusters) |
1091 | break; | 1123 | break; |
1092 | 1124 | ||
1093 | ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); | 1125 | ret = ocfs2_extend_file(inode, NULL, newsize, count); |
1094 | if (ret < 0) { | 1126 | if (ret < 0) { |
1095 | if (ret != -ENOSPC) | 1127 | if (ret != -ENOSPC) |
1096 | mlog_errno(ret); | 1128 | mlog_errno(ret); |
1097 | goto out; | 1129 | goto out_unlock; |
1098 | } | 1130 | } |
1099 | break; | 1131 | break; |
1100 | } | 1132 | } |
1101 | 1133 | ||
1102 | /* ok, we're done with i_size and alloc work */ | 1134 | if (appending) |
1103 | iocb->ki_pos = saved_pos; | 1135 | *ppos = saved_pos; |
1136 | |||
1137 | out_unlock: | ||
1104 | ocfs2_meta_unlock(inode, meta_level); | 1138 | ocfs2_meta_unlock(inode, meta_level); |
1105 | meta_level = -1; | 1139 | |
1140 | out: | ||
1141 | return ret; | ||
1142 | } | ||
1143 | |||
1144 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | ||
1145 | const struct iovec *iov, | ||
1146 | unsigned long nr_segs, | ||
1147 | loff_t pos) | ||
1148 | { | ||
1149 | int ret, rw_level, have_alloc_sem = 0; | ||
1150 | struct file *filp = iocb->ki_filp; | ||
1151 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
1152 | int appending = filp->f_flags & O_APPEND ? 1 : 0; | ||
1153 | |||
1154 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, | ||
1155 | (unsigned int)nr_segs, | ||
1156 | filp->f_path.dentry->d_name.len, | ||
1157 | filp->f_path.dentry->d_name.name); | ||
1158 | |||
1159 | /* happy write of zero bytes */ | ||
1160 | if (iocb->ki_left == 0) | ||
1161 | return 0; | ||
1162 | |||
1163 | mutex_lock(&inode->i_mutex); | ||
1164 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | ||
1165 | if (filp->f_flags & O_DIRECT) { | ||
1166 | have_alloc_sem = 1; | ||
1167 | down_read(&inode->i_alloc_sem); | ||
1168 | } | ||
1169 | |||
1170 | /* concurrent O_DIRECT writes are allowed */ | ||
1171 | rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1; | ||
1172 | ret = ocfs2_rw_lock(inode, rw_level); | ||
1173 | if (ret < 0) { | ||
1174 | rw_level = -1; | ||
1175 | mlog_errno(ret); | ||
1176 | goto out; | ||
1177 | } | ||
1178 | |||
1179 | ret = ocfs2_prepare_inode_for_write(filp->f_path.dentry, &iocb->ki_pos, | ||
1180 | iocb->ki_left, appending); | ||
1181 | if (ret < 0) { | ||
1182 | mlog_errno(ret); | ||
1183 | goto out; | ||
1184 | } | ||
1106 | 1185 | ||
1107 | /* communicate with ocfs2_dio_end_io */ | 1186 | /* communicate with ocfs2_dio_end_io */ |
1108 | ocfs2_iocb_set_rw_locked(iocb); | 1187 | ocfs2_iocb_set_rw_locked(iocb); |
@@ -1128,8 +1207,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1128 | } | 1207 | } |
1129 | 1208 | ||
1130 | out: | 1209 | out: |
1131 | if (meta_level != -1) | ||
1132 | ocfs2_meta_unlock(inode, meta_level); | ||
1133 | if (have_alloc_sem) | 1210 | if (have_alloc_sem) |
1134 | up_read(&inode->i_alloc_sem); | 1211 | up_read(&inode->i_alloc_sem); |
1135 | if (rw_level != -1) | 1212 | if (rw_level != -1) |
@@ -1140,19 +1217,90 @@ out: | |||
1140 | return ret; | 1217 | return ret; |
1141 | } | 1218 | } |
1142 | 1219 | ||
1220 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
1221 | struct file *out, | ||
1222 | loff_t *ppos, | ||
1223 | size_t len, | ||
1224 | unsigned int flags) | ||
1225 | { | ||
1226 | int ret; | ||
1227 | struct inode *inode = out->f_path.dentry->d_inode; | ||
1228 | |||
1229 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe, | ||
1230 | (unsigned int)len, | ||
1231 | out->f_path.dentry->d_name.len, | ||
1232 | out->f_path.dentry->d_name.name); | ||
1233 | |||
1234 | inode_double_lock(inode, pipe->inode); | ||
1235 | |||
1236 | ret = ocfs2_rw_lock(inode, 1); | ||
1237 | if (ret < 0) { | ||
1238 | mlog_errno(ret); | ||
1239 | goto out; | ||
1240 | } | ||
1241 | |||
1242 | ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, ppos, len, 0); | ||
1243 | if (ret < 0) { | ||
1244 | mlog_errno(ret); | ||
1245 | goto out_unlock; | ||
1246 | } | ||
1247 | |||
1248 | /* ok, we're done with i_size and alloc work */ | ||
1249 | ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); | ||
1250 | |||
1251 | out_unlock: | ||
1252 | ocfs2_rw_unlock(inode, 1); | ||
1253 | out: | ||
1254 | inode_double_unlock(inode, pipe->inode); | ||
1255 | |||
1256 | mlog_exit(ret); | ||
1257 | return ret; | ||
1258 | } | ||
1259 | |||
1260 | static ssize_t ocfs2_file_splice_read(struct file *in, | ||
1261 | loff_t *ppos, | ||
1262 | struct pipe_inode_info *pipe, | ||
1263 | size_t len, | ||
1264 | unsigned int flags) | ||
1265 | { | ||
1266 | int ret = 0; | ||
1267 | struct inode *inode = in->f_path.dentry->d_inode; | ||
1268 | |||
1269 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe, | ||
1270 | (unsigned int)len, | ||
1271 | in->f_path.dentry->d_name.len, | ||
1272 | in->f_path.dentry->d_name.name); | ||
1273 | |||
1274 | /* | ||
1275 | * See the comment in ocfs2_file_aio_read() | ||
1276 | */ | ||
1277 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
1278 | if (ret < 0) { | ||
1279 | mlog_errno(ret); | ||
1280 | goto bail; | ||
1281 | } | ||
1282 | ocfs2_meta_unlock(inode, 0); | ||
1283 | |||
1284 | ret = generic_file_splice_read(in, ppos, pipe, len, flags); | ||
1285 | |||
1286 | bail: | ||
1287 | mlog_exit(ret); | ||
1288 | return ret; | ||
1289 | } | ||
1290 | |||
1143 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | 1291 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, |
1144 | const struct iovec *iov, | 1292 | const struct iovec *iov, |
1145 | unsigned long nr_segs, | 1293 | unsigned long nr_segs, |
1146 | loff_t pos) | 1294 | loff_t pos) |
1147 | { | 1295 | { |
1148 | int ret = 0, rw_level = -1, have_alloc_sem = 0; | 1296 | int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0; |
1149 | struct file *filp = iocb->ki_filp; | 1297 | struct file *filp = iocb->ki_filp; |
1150 | struct inode *inode = filp->f_dentry->d_inode; | 1298 | struct inode *inode = filp->f_path.dentry->d_inode; |
1151 | 1299 | ||
1152 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, | 1300 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, |
1153 | (unsigned int)nr_segs, | 1301 | (unsigned int)nr_segs, |
1154 | filp->f_dentry->d_name.len, | 1302 | filp->f_path.dentry->d_name.len, |
1155 | filp->f_dentry->d_name.name); | 1303 | filp->f_path.dentry->d_name.name); |
1156 | 1304 | ||
1157 | if (!inode) { | 1305 | if (!inode) { |
1158 | ret = -EINVAL; | 1306 | ret = -EINVAL; |
@@ -1187,12 +1335,12 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
1187 | * like i_size. This allows the checks down below | 1335 | * like i_size. This allows the checks down below |
1188 | * generic_file_aio_read() a chance of actually working. | 1336 | * generic_file_aio_read() a chance of actually working. |
1189 | */ | 1337 | */ |
1190 | ret = ocfs2_meta_lock(inode, NULL, NULL, 0); | 1338 | ret = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level); |
1191 | if (ret < 0) { | 1339 | if (ret < 0) { |
1192 | mlog_errno(ret); | 1340 | mlog_errno(ret); |
1193 | goto bail; | 1341 | goto bail; |
1194 | } | 1342 | } |
1195 | ocfs2_meta_unlock(inode, 0); | 1343 | ocfs2_meta_unlock(inode, lock_level); |
1196 | 1344 | ||
1197 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); | 1345 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); |
1198 | if (ret == -EINVAL) | 1346 | if (ret == -EINVAL) |
@@ -1220,11 +1368,13 @@ bail: | |||
1220 | struct inode_operations ocfs2_file_iops = { | 1368 | struct inode_operations ocfs2_file_iops = { |
1221 | .setattr = ocfs2_setattr, | 1369 | .setattr = ocfs2_setattr, |
1222 | .getattr = ocfs2_getattr, | 1370 | .getattr = ocfs2_getattr, |
1371 | .permission = ocfs2_permission, | ||
1223 | }; | 1372 | }; |
1224 | 1373 | ||
1225 | struct inode_operations ocfs2_special_file_iops = { | 1374 | struct inode_operations ocfs2_special_file_iops = { |
1226 | .setattr = ocfs2_setattr, | 1375 | .setattr = ocfs2_setattr, |
1227 | .getattr = ocfs2_getattr, | 1376 | .getattr = ocfs2_getattr, |
1377 | .permission = ocfs2_permission, | ||
1228 | }; | 1378 | }; |
1229 | 1379 | ||
1230 | const struct file_operations ocfs2_fops = { | 1380 | const struct file_operations ocfs2_fops = { |
@@ -1238,6 +1388,8 @@ const struct file_operations ocfs2_fops = { | |||
1238 | .aio_read = ocfs2_file_aio_read, | 1388 | .aio_read = ocfs2_file_aio_read, |
1239 | .aio_write = ocfs2_file_aio_write, | 1389 | .aio_write = ocfs2_file_aio_write, |
1240 | .ioctl = ocfs2_ioctl, | 1390 | .ioctl = ocfs2_ioctl, |
1391 | .splice_read = ocfs2_file_splice_read, | ||
1392 | .splice_write = ocfs2_file_splice_write, | ||
1241 | }; | 1393 | }; |
1242 | 1394 | ||
1243 | const struct file_operations ocfs2_dops = { | 1395 | const struct file_operations ocfs2_dops = { |
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 740c9e7ca599..601a453f18a8 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -41,17 +41,24 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
41 | struct inode *inode, | 41 | struct inode *inode, |
42 | u32 clusters_to_add, | 42 | u32 clusters_to_add, |
43 | struct buffer_head *fe_bh, | 43 | struct buffer_head *fe_bh, |
44 | struct ocfs2_journal_handle *handle, | 44 | handle_t *handle, |
45 | struct ocfs2_alloc_context *data_ac, | 45 | struct ocfs2_alloc_context *data_ac, |
46 | struct ocfs2_alloc_context *meta_ac, | 46 | struct ocfs2_alloc_context *meta_ac, |
47 | enum ocfs2_alloc_restarted *reason); | 47 | enum ocfs2_alloc_restarted *reason); |
48 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 48 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
49 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 49 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
50 | struct kstat *stat); | 50 | struct kstat *stat); |
51 | int ocfs2_permission(struct inode *inode, int mask, | ||
52 | struct nameidata *nd); | ||
51 | 53 | ||
52 | int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, | 54 | int ocfs2_set_inode_size(handle_t *handle, |
53 | struct inode *inode, | 55 | struct inode *inode, |
54 | struct buffer_head *fe_bh, | 56 | struct buffer_head *fe_bh, |
55 | u64 new_i_size); | 57 | u64 new_i_size); |
56 | 58 | ||
59 | int ocfs2_should_update_atime(struct inode *inode, | ||
60 | struct vfsmount *vfsmnt); | ||
61 | int ocfs2_update_inode_atime(struct inode *inode, | ||
62 | struct buffer_head *bh); | ||
63 | |||
57 | #endif /* OCFS2_FILE_H */ | 64 | #endif /* OCFS2_FILE_H */ |
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index cbfd45a97a63..8fc52d6d0ce7 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c | |||
@@ -154,6 +154,9 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb) | |||
154 | { | 154 | { |
155 | int status; | 155 | int status; |
156 | 156 | ||
157 | if (ocfs2_mount_local(osb)) | ||
158 | return 0; | ||
159 | |||
157 | status = o2hb_register_callback(&osb->osb_hb_down); | 160 | status = o2hb_register_callback(&osb->osb_hb_down); |
158 | if (status < 0) { | 161 | if (status < 0) { |
159 | mlog_errno(status); | 162 | mlog_errno(status); |
@@ -172,6 +175,9 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) | |||
172 | { | 175 | { |
173 | int status; | 176 | int status; |
174 | 177 | ||
178 | if (ocfs2_mount_local(osb)) | ||
179 | return; | ||
180 | |||
175 | status = o2hb_unregister_callback(&osb->osb_hb_down); | 181 | status = o2hb_unregister_callback(&osb->osb_hb_down); |
176 | if (status < 0) | 182 | if (status < 0) |
177 | mlog_errno(status); | 183 | mlog_errno(status); |
@@ -186,6 +192,9 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb) | |||
186 | int ret; | 192 | int ret; |
187 | char *argv[5], *envp[3]; | 193 | char *argv[5], *envp[3]; |
188 | 194 | ||
195 | if (ocfs2_mount_local(osb)) | ||
196 | return; | ||
197 | |||
189 | if (!osb->uuid_str) { | 198 | if (!osb->uuid_str) { |
190 | /* This can happen if we don't get far enough in mount... */ | 199 | /* This can happen if we don't get far enough in mount... */ |
191 | mlog(0, "No UUID with which to stop heartbeat!\n\n"); | 200 | mlog(0, "No UUID with which to stop heartbeat!\n\n"); |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 16e8e74dc966..e4d91493d7d7 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -360,7 +360,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
360 | inode); | 360 | inode); |
361 | 361 | ||
362 | ocfs2_set_inode_flags(inode); | 362 | ocfs2_set_inode_flags(inode); |
363 | inode->i_flags |= S_NOATIME; | ||
364 | 363 | ||
365 | status = 0; | 364 | status = 0; |
366 | bail: | 365 | bail: |
@@ -424,7 +423,8 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
424 | * cluster lock before trusting anything anyway. | 423 | * cluster lock before trusting anything anyway. |
425 | */ | 424 | */ |
426 | can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE) | 425 | can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE) |
427 | && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK); | 426 | && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK) |
427 | && !ocfs2_mount_local(osb); | ||
428 | 428 | ||
429 | /* | 429 | /* |
430 | * To maintain backwards compatibility with older versions of | 430 | * To maintain backwards compatibility with older versions of |
@@ -441,7 +441,7 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
441 | generation, inode); | 441 | generation, inode); |
442 | 442 | ||
443 | if (can_lock) { | 443 | if (can_lock) { |
444 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 444 | status = ocfs2_meta_lock(inode, NULL, 0); |
445 | if (status) { | 445 | if (status) { |
446 | make_bad_inode(inode); | 446 | make_bad_inode(inode); |
447 | mlog_errno(status); | 447 | mlog_errno(status); |
@@ -512,7 +512,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
512 | struct buffer_head *fe_bh) | 512 | struct buffer_head *fe_bh) |
513 | { | 513 | { |
514 | int status = 0; | 514 | int status = 0; |
515 | struct ocfs2_journal_handle *handle = NULL; | 515 | handle_t *handle = NULL; |
516 | struct ocfs2_truncate_context *tc = NULL; | 516 | struct ocfs2_truncate_context *tc = NULL; |
517 | struct ocfs2_dinode *fe; | 517 | struct ocfs2_dinode *fe; |
518 | 518 | ||
@@ -524,7 +524,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
524 | if (!fe->i_clusters) | 524 | if (!fe->i_clusters) |
525 | goto bail; | 525 | goto bail; |
526 | 526 | ||
527 | handle = ocfs2_start_trans(osb, handle, OCFS2_INODE_UPDATE_CREDITS); | 527 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
528 | if (IS_ERR(handle)) { | 528 | if (IS_ERR(handle)) { |
529 | status = PTR_ERR(handle); | 529 | status = PTR_ERR(handle); |
530 | handle = NULL; | 530 | handle = NULL; |
@@ -538,7 +538,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
538 | goto bail; | 538 | goto bail; |
539 | } | 539 | } |
540 | 540 | ||
541 | ocfs2_commit_trans(handle); | 541 | ocfs2_commit_trans(osb, handle); |
542 | handle = NULL; | 542 | handle = NULL; |
543 | 543 | ||
544 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); | 544 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); |
@@ -554,7 +554,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
554 | } | 554 | } |
555 | bail: | 555 | bail: |
556 | if (handle) | 556 | if (handle) |
557 | ocfs2_commit_trans(handle); | 557 | ocfs2_commit_trans(osb, handle); |
558 | 558 | ||
559 | mlog_exit(status); | 559 | mlog_exit(status); |
560 | return status; | 560 | return status; |
@@ -568,7 +568,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
568 | int status; | 568 | int status; |
569 | struct inode *inode_alloc_inode = NULL; | 569 | struct inode *inode_alloc_inode = NULL; |
570 | struct buffer_head *inode_alloc_bh = NULL; | 570 | struct buffer_head *inode_alloc_bh = NULL; |
571 | struct ocfs2_journal_handle *handle; | 571 | handle_t *handle; |
572 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 572 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
573 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; | 573 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
574 | 574 | ||
@@ -582,7 +582,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
582 | } | 582 | } |
583 | 583 | ||
584 | mutex_lock(&inode_alloc_inode->i_mutex); | 584 | mutex_lock(&inode_alloc_inode->i_mutex); |
585 | status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1); | 585 | status = ocfs2_meta_lock(inode_alloc_inode, &inode_alloc_bh, 1); |
586 | if (status < 0) { | 586 | if (status < 0) { |
587 | mutex_unlock(&inode_alloc_inode->i_mutex); | 587 | mutex_unlock(&inode_alloc_inode->i_mutex); |
588 | 588 | ||
@@ -590,7 +590,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
590 | goto bail; | 590 | goto bail; |
591 | } | 591 | } |
592 | 592 | ||
593 | handle = ocfs2_start_trans(osb, NULL, OCFS2_DELETE_INODE_CREDITS); | 593 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS); |
594 | if (IS_ERR(handle)) { | 594 | if (IS_ERR(handle)) { |
595 | status = PTR_ERR(handle); | 595 | status = PTR_ERR(handle); |
596 | mlog_errno(status); | 596 | mlog_errno(status); |
@@ -629,7 +629,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
629 | mlog_errno(status); | 629 | mlog_errno(status); |
630 | 630 | ||
631 | bail_commit: | 631 | bail_commit: |
632 | ocfs2_commit_trans(handle); | 632 | ocfs2_commit_trans(osb, handle); |
633 | bail_unlock: | 633 | bail_unlock: |
634 | ocfs2_meta_unlock(inode_alloc_inode, 1); | 634 | ocfs2_meta_unlock(inode_alloc_inode, 1); |
635 | mutex_unlock(&inode_alloc_inode->i_mutex); | 635 | mutex_unlock(&inode_alloc_inode->i_mutex); |
@@ -705,7 +705,7 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
705 | * delete_inode operation. We do this now to avoid races with | 705 | * delete_inode operation. We do this now to avoid races with |
706 | * recovery completion on other nodes. */ | 706 | * recovery completion on other nodes. */ |
707 | mutex_lock(&orphan_dir_inode->i_mutex); | 707 | mutex_lock(&orphan_dir_inode->i_mutex); |
708 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1); | 708 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
709 | if (status < 0) { | 709 | if (status < 0) { |
710 | mutex_unlock(&orphan_dir_inode->i_mutex); | 710 | mutex_unlock(&orphan_dir_inode->i_mutex); |
711 | 711 | ||
@@ -933,7 +933,7 @@ void ocfs2_delete_inode(struct inode *inode) | |||
933 | * allocation lock here as it won't be needed - nobody will | 933 | * allocation lock here as it won't be needed - nobody will |
934 | * have the file open. | 934 | * have the file open. |
935 | */ | 935 | */ |
936 | status = ocfs2_meta_lock(inode, NULL, &di_bh, 1); | 936 | status = ocfs2_meta_lock(inode, &di_bh, 1); |
937 | if (status < 0) { | 937 | if (status < 0) { |
938 | if (status != -ENOENT) | 938 | if (status != -ENOENT) |
939 | mlog_errno(status); | 939 | mlog_errno(status); |
@@ -1067,12 +1067,6 @@ void ocfs2_clear_inode(struct inode *inode) | |||
1067 | mlog_bug_on_msg(oi->ip_open_count, | 1067 | mlog_bug_on_msg(oi->ip_open_count, |
1068 | "Clear inode of %llu has open count %d\n", | 1068 | "Clear inode of %llu has open count %d\n", |
1069 | (unsigned long long)oi->ip_blkno, oi->ip_open_count); | 1069 | (unsigned long long)oi->ip_blkno, oi->ip_open_count); |
1070 | mlog_bug_on_msg(!list_empty(&oi->ip_handle_list), | ||
1071 | "Clear inode of %llu has non empty handle list\n", | ||
1072 | (unsigned long long)oi->ip_blkno); | ||
1073 | mlog_bug_on_msg(oi->ip_handle, | ||
1074 | "Clear inode of %llu has non empty handle pointer\n", | ||
1075 | (unsigned long long)oi->ip_blkno); | ||
1076 | 1070 | ||
1077 | /* Clear all other flags. */ | 1071 | /* Clear all other flags. */ |
1078 | oi->ip_flags = OCFS2_INODE_CACHE_INLINE; | 1072 | oi->ip_flags = OCFS2_INODE_CACHE_INLINE; |
@@ -1186,7 +1180,7 @@ int ocfs2_inode_revalidate(struct dentry *dentry) | |||
1186 | 1180 | ||
1187 | /* Let ocfs2_meta_lock do the work of updating our struct | 1181 | /* Let ocfs2_meta_lock do the work of updating our struct |
1188 | * inode for us. */ | 1182 | * inode for us. */ |
1189 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 1183 | status = ocfs2_meta_lock(inode, NULL, 0); |
1190 | if (status < 0) { | 1184 | if (status < 0) { |
1191 | if (status != -ENOENT) | 1185 | if (status != -ENOENT) |
1192 | mlog_errno(status); | 1186 | mlog_errno(status); |
@@ -1204,7 +1198,7 @@ bail: | |||
1204 | * struct inode. | 1198 | * struct inode. |
1205 | * Only takes ip_lock. | 1199 | * Only takes ip_lock. |
1206 | */ | 1200 | */ |
1207 | int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, | 1201 | int ocfs2_mark_inode_dirty(handle_t *handle, |
1208 | struct inode *inode, | 1202 | struct inode *inode, |
1209 | struct buffer_head *bh) | 1203 | struct buffer_head *bh) |
1210 | { | 1204 | { |
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 9957810fdf85..1a7dd2945b34 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h | |||
@@ -48,13 +48,6 @@ struct ocfs2_inode_info | |||
48 | 48 | ||
49 | struct mutex ip_io_mutex; | 49 | struct mutex ip_io_mutex; |
50 | 50 | ||
51 | /* Used by the journalling code to attach an inode to a | ||
52 | * handle. These are protected by ip_io_mutex in order to lock | ||
53 | * out other I/O to the inode until we either commit or | ||
54 | * abort. */ | ||
55 | struct list_head ip_handle_list; | ||
56 | struct ocfs2_journal_handle *ip_handle; | ||
57 | |||
58 | u32 ip_flags; /* see below */ | 51 | u32 ip_flags; /* see below */ |
59 | u32 ip_attr; /* inode attributes */ | 52 | u32 ip_attr; /* inode attributes */ |
60 | 53 | ||
@@ -113,7 +106,7 @@ static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) | |||
113 | #define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL) | 106 | #define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL) |
114 | #define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL) | 107 | #define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL) |
115 | 108 | ||
116 | extern kmem_cache_t *ocfs2_inode_cache; | 109 | extern struct kmem_cache *ocfs2_inode_cache; |
117 | 110 | ||
118 | extern const struct address_space_operations ocfs2_aops; | 111 | extern const struct address_space_operations ocfs2_aops; |
119 | 112 | ||
@@ -143,7 +136,7 @@ ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf, | |||
143 | void ocfs2_sync_blockdev(struct super_block *sb); | 136 | void ocfs2_sync_blockdev(struct super_block *sb); |
144 | void ocfs2_refresh_inode(struct inode *inode, | 137 | void ocfs2_refresh_inode(struct inode *inode, |
145 | struct ocfs2_dinode *fe); | 138 | struct ocfs2_dinode *fe); |
146 | int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, | 139 | int ocfs2_mark_inode_dirty(handle_t *handle, |
147 | struct inode *inode, | 140 | struct inode *inode, |
148 | struct buffer_head *bh); | 141 | struct buffer_head *bh); |
149 | int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); | 142 | int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 3663cef80689..4768be5f3086 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -26,7 +26,7 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) | |||
26 | { | 26 | { |
27 | int status; | 27 | int status; |
28 | 28 | ||
29 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 29 | status = ocfs2_meta_lock(inode, NULL, 0); |
30 | if (status < 0) { | 30 | if (status < 0) { |
31 | mlog_errno(status); | 31 | mlog_errno(status); |
32 | return status; | 32 | return status; |
@@ -43,14 +43,14 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
43 | { | 43 | { |
44 | struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); | 44 | struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); |
45 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 45 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
46 | struct ocfs2_journal_handle *handle = NULL; | 46 | handle_t *handle = NULL; |
47 | struct buffer_head *bh = NULL; | 47 | struct buffer_head *bh = NULL; |
48 | unsigned oldflags; | 48 | unsigned oldflags; |
49 | int status; | 49 | int status; |
50 | 50 | ||
51 | mutex_lock(&inode->i_mutex); | 51 | mutex_lock(&inode->i_mutex); |
52 | 52 | ||
53 | status = ocfs2_meta_lock(inode, NULL, &bh, 1); | 53 | status = ocfs2_meta_lock(inode, &bh, 1); |
54 | if (status < 0) { | 54 | if (status < 0) { |
55 | mlog_errno(status); | 55 | mlog_errno(status); |
56 | goto bail; | 56 | goto bail; |
@@ -67,7 +67,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
67 | if (!S_ISDIR(inode->i_mode)) | 67 | if (!S_ISDIR(inode->i_mode)) |
68 | flags &= ~OCFS2_DIRSYNC_FL; | 68 | flags &= ~OCFS2_DIRSYNC_FL; |
69 | 69 | ||
70 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 70 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
71 | if (IS_ERR(handle)) { | 71 | if (IS_ERR(handle)) { |
72 | status = PTR_ERR(handle); | 72 | status = PTR_ERR(handle); |
73 | mlog_errno(status); | 73 | mlog_errno(status); |
@@ -96,7 +96,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
96 | if (status < 0) | 96 | if (status < 0) |
97 | mlog_errno(status); | 97 | mlog_errno(status); |
98 | 98 | ||
99 | ocfs2_commit_trans(handle); | 99 | ocfs2_commit_trans(osb, handle); |
100 | bail_unlock: | 100 | bail_unlock: |
101 | ocfs2_meta_unlock(inode, 1); | 101 | ocfs2_meta_unlock(inode, 1); |
102 | bail: | 102 | bail: |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index fd9734def551..825cb0ae1b4c 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
@@ -57,9 +57,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, | |||
57 | static int __ocfs2_recovery_thread(void *arg); | 57 | static int __ocfs2_recovery_thread(void *arg); |
58 | static int ocfs2_commit_cache(struct ocfs2_super *osb); | 58 | static int ocfs2_commit_cache(struct ocfs2_super *osb); |
59 | static int ocfs2_wait_on_mount(struct ocfs2_super *osb); | 59 | static int ocfs2_wait_on_mount(struct ocfs2_super *osb); |
60 | static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal, | ||
61 | struct ocfs2_journal_handle *handle); | ||
62 | static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle); | ||
63 | static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, | 60 | static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, |
64 | int dirty); | 61 | int dirty); |
65 | static int ocfs2_trylock_journal(struct ocfs2_super *osb, | 62 | static int ocfs2_trylock_journal(struct ocfs2_super *osb, |
@@ -113,46 +110,18 @@ finally: | |||
113 | return status; | 110 | return status; |
114 | } | 111 | } |
115 | 112 | ||
116 | struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb) | ||
117 | { | ||
118 | struct ocfs2_journal_handle *retval = NULL; | ||
119 | |||
120 | retval = kcalloc(1, sizeof(*retval), GFP_NOFS); | ||
121 | if (!retval) { | ||
122 | mlog(ML_ERROR, "Failed to allocate memory for journal " | ||
123 | "handle!\n"); | ||
124 | return NULL; | ||
125 | } | ||
126 | |||
127 | retval->max_buffs = 0; | ||
128 | retval->num_locks = 0; | ||
129 | retval->k_handle = NULL; | ||
130 | |||
131 | INIT_LIST_HEAD(&retval->locks); | ||
132 | INIT_LIST_HEAD(&retval->inode_list); | ||
133 | retval->journal = osb->journal; | ||
134 | |||
135 | return retval; | ||
136 | } | ||
137 | |||
138 | /* pass it NULL and it will allocate a new handle object for you. If | 113 | /* pass it NULL and it will allocate a new handle object for you. If |
139 | * you pass it a handle however, it may still return error, in which | 114 | * you pass it a handle however, it may still return error, in which |
140 | * case it has free'd the passed handle for you. */ | 115 | * case it has free'd the passed handle for you. */ |
141 | struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | 116 | handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs) |
142 | struct ocfs2_journal_handle *handle, | ||
143 | int max_buffs) | ||
144 | { | 117 | { |
145 | int ret; | ||
146 | journal_t *journal = osb->journal->j_journal; | 118 | journal_t *journal = osb->journal->j_journal; |
147 | 119 | handle_t *handle; | |
148 | mlog_entry("(max_buffs = %d)\n", max_buffs); | ||
149 | 120 | ||
150 | BUG_ON(!osb || !osb->journal->j_journal); | 121 | BUG_ON(!osb || !osb->journal->j_journal); |
151 | 122 | ||
152 | if (ocfs2_is_hard_readonly(osb)) { | 123 | if (ocfs2_is_hard_readonly(osb)) |
153 | ret = -EROFS; | 124 | return ERR_PTR(-EROFS); |
154 | goto done_free; | ||
155 | } | ||
156 | 125 | ||
157 | BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); | 126 | BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); |
158 | BUG_ON(max_buffs <= 0); | 127 | BUG_ON(max_buffs <= 0); |
@@ -163,154 +132,41 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | |||
163 | BUG(); | 132 | BUG(); |
164 | } | 133 | } |
165 | 134 | ||
166 | if (!handle) | ||
167 | handle = ocfs2_alloc_handle(osb); | ||
168 | if (!handle) { | ||
169 | ret = -ENOMEM; | ||
170 | mlog(ML_ERROR, "Failed to allocate memory for journal " | ||
171 | "handle!\n"); | ||
172 | goto done_free; | ||
173 | } | ||
174 | |||
175 | handle->max_buffs = max_buffs; | ||
176 | |||
177 | down_read(&osb->journal->j_trans_barrier); | 135 | down_read(&osb->journal->j_trans_barrier); |
178 | 136 | ||
179 | /* actually start the transaction now */ | 137 | handle = journal_start(journal, max_buffs); |
180 | handle->k_handle = journal_start(journal, max_buffs); | 138 | if (IS_ERR(handle)) { |
181 | if (IS_ERR(handle->k_handle)) { | ||
182 | up_read(&osb->journal->j_trans_barrier); | 139 | up_read(&osb->journal->j_trans_barrier); |
183 | 140 | ||
184 | ret = PTR_ERR(handle->k_handle); | 141 | mlog_errno(PTR_ERR(handle)); |
185 | handle->k_handle = NULL; | ||
186 | mlog_errno(ret); | ||
187 | 142 | ||
188 | if (is_journal_aborted(journal)) { | 143 | if (is_journal_aborted(journal)) { |
189 | ocfs2_abort(osb->sb, "Detected aborted journal"); | 144 | ocfs2_abort(osb->sb, "Detected aborted journal"); |
190 | ret = -EROFS; | 145 | handle = ERR_PTR(-EROFS); |
191 | } | 146 | } |
192 | goto done_free; | 147 | } else { |
148 | if (!ocfs2_mount_local(osb)) | ||
149 | atomic_inc(&(osb->journal->j_num_trans)); | ||
193 | } | 150 | } |
194 | 151 | ||
195 | atomic_inc(&(osb->journal->j_num_trans)); | ||
196 | handle->flags |= OCFS2_HANDLE_STARTED; | ||
197 | |||
198 | mlog_exit_ptr(handle); | ||
199 | return handle; | 152 | return handle; |
200 | |||
201 | done_free: | ||
202 | if (handle) | ||
203 | ocfs2_commit_unstarted_handle(handle); /* will kfree handle */ | ||
204 | |||
205 | mlog_exit(ret); | ||
206 | return ERR_PTR(ret); | ||
207 | } | ||
208 | |||
209 | void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle, | ||
210 | struct inode *inode) | ||
211 | { | ||
212 | BUG_ON(!handle); | ||
213 | BUG_ON(!inode); | ||
214 | |||
215 | atomic_inc(&inode->i_count); | ||
216 | |||
217 | /* we're obviously changing it... */ | ||
218 | mutex_lock(&inode->i_mutex); | ||
219 | |||
220 | /* sanity check */ | ||
221 | BUG_ON(OCFS2_I(inode)->ip_handle); | ||
222 | BUG_ON(!list_empty(&OCFS2_I(inode)->ip_handle_list)); | ||
223 | |||
224 | OCFS2_I(inode)->ip_handle = handle; | ||
225 | list_move_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list)); | ||
226 | } | ||
227 | |||
228 | static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle) | ||
229 | { | ||
230 | struct list_head *p, *n; | ||
231 | struct inode *inode; | ||
232 | struct ocfs2_inode_info *oi; | ||
233 | |||
234 | list_for_each_safe(p, n, &handle->inode_list) { | ||
235 | oi = list_entry(p, struct ocfs2_inode_info, | ||
236 | ip_handle_list); | ||
237 | inode = &oi->vfs_inode; | ||
238 | |||
239 | OCFS2_I(inode)->ip_handle = NULL; | ||
240 | list_del_init(&OCFS2_I(inode)->ip_handle_list); | ||
241 | |||
242 | mutex_unlock(&inode->i_mutex); | ||
243 | iput(inode); | ||
244 | } | ||
245 | } | 153 | } |
246 | 154 | ||
247 | /* This is trivial so we do it out of the main commit | 155 | int ocfs2_commit_trans(struct ocfs2_super *osb, |
248 | * paths. Beware, it can be called from start_trans too! */ | 156 | handle_t *handle) |
249 | static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle) | ||
250 | { | 157 | { |
251 | mlog_entry_void(); | 158 | int ret; |
252 | 159 | struct ocfs2_journal *journal = osb->journal; | |
253 | BUG_ON(handle->flags & OCFS2_HANDLE_STARTED); | ||
254 | |||
255 | ocfs2_handle_unlock_inodes(handle); | ||
256 | /* You are allowed to add journal locks before the transaction | ||
257 | * has started. */ | ||
258 | ocfs2_handle_cleanup_locks(handle->journal, handle); | ||
259 | |||
260 | kfree(handle); | ||
261 | |||
262 | mlog_exit_void(); | ||
263 | } | ||
264 | |||
265 | void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) | ||
266 | { | ||
267 | handle_t *jbd_handle; | ||
268 | int retval; | ||
269 | struct ocfs2_journal *journal = handle->journal; | ||
270 | |||
271 | mlog_entry_void(); | ||
272 | 160 | ||
273 | BUG_ON(!handle); | 161 | BUG_ON(!handle); |
274 | 162 | ||
275 | if (!(handle->flags & OCFS2_HANDLE_STARTED)) { | 163 | ret = journal_stop(handle); |
276 | ocfs2_commit_unstarted_handle(handle); | 164 | if (ret < 0) |
277 | mlog_exit_void(); | 165 | mlog_errno(ret); |
278 | return; | ||
279 | } | ||
280 | |||
281 | /* release inode semaphores we took during this transaction */ | ||
282 | ocfs2_handle_unlock_inodes(handle); | ||
283 | |||
284 | /* ocfs2_extend_trans may have had to call journal_restart | ||
285 | * which will always commit the transaction, but may return | ||
286 | * error for any number of reasons. If this is the case, we | ||
287 | * clear k_handle as it's not valid any more. */ | ||
288 | if (handle->k_handle) { | ||
289 | jbd_handle = handle->k_handle; | ||
290 | |||
291 | if (handle->flags & OCFS2_HANDLE_SYNC) | ||
292 | jbd_handle->h_sync = 1; | ||
293 | else | ||
294 | jbd_handle->h_sync = 0; | ||
295 | |||
296 | /* actually stop the transaction. if we've set h_sync, | ||
297 | * it'll have been committed when we return */ | ||
298 | retval = journal_stop(jbd_handle); | ||
299 | if (retval < 0) { | ||
300 | mlog_errno(retval); | ||
301 | mlog(ML_ERROR, "Could not commit transaction\n"); | ||
302 | BUG(); | ||
303 | } | ||
304 | |||
305 | handle->k_handle = NULL; /* it's been free'd in journal_stop */ | ||
306 | } | ||
307 | |||
308 | ocfs2_handle_cleanup_locks(journal, handle); | ||
309 | 166 | ||
310 | up_read(&journal->j_trans_barrier); | 167 | up_read(&journal->j_trans_barrier); |
311 | 168 | ||
312 | kfree(handle); | 169 | return ret; |
313 | mlog_exit_void(); | ||
314 | } | 170 | } |
315 | 171 | ||
316 | /* | 172 | /* |
@@ -326,20 +182,18 @@ void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) | |||
326 | * good because transaction ids haven't yet been recorded on the | 182 | * good because transaction ids haven't yet been recorded on the |
327 | * cluster locks associated with this handle. | 183 | * cluster locks associated with this handle. |
328 | */ | 184 | */ |
329 | int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | 185 | int ocfs2_extend_trans(handle_t *handle, int nblocks) |
330 | int nblocks) | ||
331 | { | 186 | { |
332 | int status; | 187 | int status; |
333 | 188 | ||
334 | BUG_ON(!handle); | 189 | BUG_ON(!handle); |
335 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
336 | BUG_ON(!nblocks); | 190 | BUG_ON(!nblocks); |
337 | 191 | ||
338 | mlog_entry_void(); | 192 | mlog_entry_void(); |
339 | 193 | ||
340 | mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); | 194 | mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); |
341 | 195 | ||
342 | status = journal_extend(handle->k_handle, nblocks); | 196 | status = journal_extend(handle, nblocks); |
343 | if (status < 0) { | 197 | if (status < 0) { |
344 | mlog_errno(status); | 198 | mlog_errno(status); |
345 | goto bail; | 199 | goto bail; |
@@ -347,15 +201,12 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | |||
347 | 201 | ||
348 | if (status > 0) { | 202 | if (status > 0) { |
349 | mlog(0, "journal_extend failed, trying journal_restart\n"); | 203 | mlog(0, "journal_extend failed, trying journal_restart\n"); |
350 | status = journal_restart(handle->k_handle, nblocks); | 204 | status = journal_restart(handle, nblocks); |
351 | if (status < 0) { | 205 | if (status < 0) { |
352 | handle->k_handle = NULL; | ||
353 | mlog_errno(status); | 206 | mlog_errno(status); |
354 | goto bail; | 207 | goto bail; |
355 | } | 208 | } |
356 | handle->max_buffs = nblocks; | 209 | } |
357 | } else | ||
358 | handle->max_buffs += nblocks; | ||
359 | 210 | ||
360 | status = 0; | 211 | status = 0; |
361 | bail: | 212 | bail: |
@@ -364,7 +215,7 @@ bail: | |||
364 | return status; | 215 | return status; |
365 | } | 216 | } |
366 | 217 | ||
367 | int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | 218 | int ocfs2_journal_access(handle_t *handle, |
368 | struct inode *inode, | 219 | struct inode *inode, |
369 | struct buffer_head *bh, | 220 | struct buffer_head *bh, |
370 | int type) | 221 | int type) |
@@ -374,7 +225,6 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
374 | BUG_ON(!inode); | 225 | BUG_ON(!inode); |
375 | BUG_ON(!handle); | 226 | BUG_ON(!handle); |
376 | BUG_ON(!bh); | 227 | BUG_ON(!bh); |
377 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
378 | 228 | ||
379 | mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", | 229 | mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", |
380 | (unsigned long long)bh->b_blocknr, type, | 230 | (unsigned long long)bh->b_blocknr, type, |
@@ -403,11 +253,11 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
403 | switch (type) { | 253 | switch (type) { |
404 | case OCFS2_JOURNAL_ACCESS_CREATE: | 254 | case OCFS2_JOURNAL_ACCESS_CREATE: |
405 | case OCFS2_JOURNAL_ACCESS_WRITE: | 255 | case OCFS2_JOURNAL_ACCESS_WRITE: |
406 | status = journal_get_write_access(handle->k_handle, bh); | 256 | status = journal_get_write_access(handle, bh); |
407 | break; | 257 | break; |
408 | 258 | ||
409 | case OCFS2_JOURNAL_ACCESS_UNDO: | 259 | case OCFS2_JOURNAL_ACCESS_UNDO: |
410 | status = journal_get_undo_access(handle->k_handle, bh); | 260 | status = journal_get_undo_access(handle, bh); |
411 | break; | 261 | break; |
412 | 262 | ||
413 | default: | 263 | default: |
@@ -424,17 +274,15 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
424 | return status; | 274 | return status; |
425 | } | 275 | } |
426 | 276 | ||
427 | int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, | 277 | int ocfs2_journal_dirty(handle_t *handle, |
428 | struct buffer_head *bh) | 278 | struct buffer_head *bh) |
429 | { | 279 | { |
430 | int status; | 280 | int status; |
431 | 281 | ||
432 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
433 | |||
434 | mlog_entry("(bh->b_blocknr=%llu)\n", | 282 | mlog_entry("(bh->b_blocknr=%llu)\n", |
435 | (unsigned long long)bh->b_blocknr); | 283 | (unsigned long long)bh->b_blocknr); |
436 | 284 | ||
437 | status = journal_dirty_metadata(handle->k_handle, bh); | 285 | status = journal_dirty_metadata(handle, bh); |
438 | if (status < 0) | 286 | if (status < 0) |
439 | mlog(ML_ERROR, "Could not dirty metadata buffer. " | 287 | mlog(ML_ERROR, "Could not dirty metadata buffer. " |
440 | "(bh->b_blocknr=%llu)\n", | 288 | "(bh->b_blocknr=%llu)\n", |
@@ -456,59 +304,6 @@ int ocfs2_journal_dirty_data(handle_t *handle, | |||
456 | return err; | 304 | return err; |
457 | } | 305 | } |
458 | 306 | ||
459 | /* We always assume you're adding a metadata lock at level 'ex' */ | ||
460 | int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle, | ||
461 | struct inode *inode) | ||
462 | { | ||
463 | int status; | ||
464 | struct ocfs2_journal_lock *lock; | ||
465 | |||
466 | BUG_ON(!inode); | ||
467 | |||
468 | lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS); | ||
469 | if (!lock) { | ||
470 | status = -ENOMEM; | ||
471 | mlog_errno(-ENOMEM); | ||
472 | goto bail; | ||
473 | } | ||
474 | |||
475 | if (!igrab(inode)) | ||
476 | BUG(); | ||
477 | lock->jl_inode = inode; | ||
478 | |||
479 | list_add_tail(&(lock->jl_lock_list), &(handle->locks)); | ||
480 | handle->num_locks++; | ||
481 | |||
482 | status = 0; | ||
483 | bail: | ||
484 | mlog_exit(status); | ||
485 | return status; | ||
486 | } | ||
487 | |||
488 | static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal, | ||
489 | struct ocfs2_journal_handle *handle) | ||
490 | { | ||
491 | struct list_head *p, *n; | ||
492 | struct ocfs2_journal_lock *lock; | ||
493 | struct inode *inode; | ||
494 | |||
495 | list_for_each_safe(p, n, &(handle->locks)) { | ||
496 | lock = list_entry(p, struct ocfs2_journal_lock, | ||
497 | jl_lock_list); | ||
498 | list_del(&lock->jl_lock_list); | ||
499 | handle->num_locks--; | ||
500 | |||
501 | inode = lock->jl_inode; | ||
502 | ocfs2_meta_unlock(inode, 1); | ||
503 | if (atomic_read(&inode->i_count) == 1) | ||
504 | mlog(ML_ERROR, | ||
505 | "Inode %llu, I'm doing a last iput for!", | ||
506 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
507 | iput(inode); | ||
508 | kmem_cache_free(ocfs2_lock_cache, lock); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | #define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) | 307 | #define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) |
513 | 308 | ||
514 | void ocfs2_set_journal_params(struct ocfs2_super *osb) | 309 | void ocfs2_set_journal_params(struct ocfs2_super *osb) |
@@ -562,8 +357,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) | |||
562 | /* Skip recovery waits here - journal inode metadata never | 357 | /* Skip recovery waits here - journal inode metadata never |
563 | * changes in a live cluster so it can be considered an | 358 | * changes in a live cluster so it can be considered an |
564 | * exception to the rule. */ | 359 | * exception to the rule. */ |
565 | status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, | 360 | status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY); |
566 | OCFS2_META_LOCK_RECOVERY); | ||
567 | if (status < 0) { | 361 | if (status < 0) { |
568 | if (status != -ERESTARTSYS) | 362 | if (status != -ERESTARTSYS) |
569 | mlog(ML_ERROR, "Could not get lock on journal!\n"); | 363 | mlog(ML_ERROR, "Could not get lock on journal!\n"); |
@@ -715,9 +509,23 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) | |||
715 | 509 | ||
716 | BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0); | 510 | BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0); |
717 | 511 | ||
718 | status = ocfs2_journal_toggle_dirty(osb, 0); | 512 | if (ocfs2_mount_local(osb)) { |
719 | if (status < 0) | 513 | journal_lock_updates(journal->j_journal); |
720 | mlog_errno(status); | 514 | status = journal_flush(journal->j_journal); |
515 | journal_unlock_updates(journal->j_journal); | ||
516 | if (status < 0) | ||
517 | mlog_errno(status); | ||
518 | } | ||
519 | |||
520 | if (status == 0) { | ||
521 | /* | ||
522 | * Do not toggle if flush was unsuccessful otherwise | ||
523 | * will leave dirty metadata in a "clean" journal | ||
524 | */ | ||
525 | status = ocfs2_journal_toggle_dirty(osb, 0); | ||
526 | if (status < 0) | ||
527 | mlog_errno(status); | ||
528 | } | ||
721 | 529 | ||
722 | /* Shutdown the kernel journal system */ | 530 | /* Shutdown the kernel journal system */ |
723 | journal_destroy(journal->j_journal); | 531 | journal_destroy(journal->j_journal); |
@@ -757,7 +565,7 @@ static void ocfs2_clear_journal_error(struct super_block *sb, | |||
757 | } | 565 | } |
758 | } | 566 | } |
759 | 567 | ||
760 | int ocfs2_journal_load(struct ocfs2_journal *journal) | 568 | int ocfs2_journal_load(struct ocfs2_journal *journal, int local) |
761 | { | 569 | { |
762 | int status = 0; | 570 | int status = 0; |
763 | struct ocfs2_super *osb; | 571 | struct ocfs2_super *osb; |
@@ -784,14 +592,18 @@ int ocfs2_journal_load(struct ocfs2_journal *journal) | |||
784 | } | 592 | } |
785 | 593 | ||
786 | /* Launch the commit thread */ | 594 | /* Launch the commit thread */ |
787 | osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt"); | 595 | if (!local) { |
788 | if (IS_ERR(osb->commit_task)) { | 596 | osb->commit_task = kthread_run(ocfs2_commit_thread, osb, |
789 | status = PTR_ERR(osb->commit_task); | 597 | "ocfs2cmt"); |
598 | if (IS_ERR(osb->commit_task)) { | ||
599 | status = PTR_ERR(osb->commit_task); | ||
600 | osb->commit_task = NULL; | ||
601 | mlog(ML_ERROR, "unable to launch ocfs2commit thread, " | ||
602 | "error=%d", status); | ||
603 | goto done; | ||
604 | } | ||
605 | } else | ||
790 | osb->commit_task = NULL; | 606 | osb->commit_task = NULL; |
791 | mlog(ML_ERROR, "unable to launch ocfs2commit thread, error=%d", | ||
792 | status); | ||
793 | goto done; | ||
794 | } | ||
795 | 607 | ||
796 | done: | 608 | done: |
797 | mlog_exit(status); | 609 | mlog_exit(status); |
@@ -911,11 +723,12 @@ struct ocfs2_la_recovery_item { | |||
911 | * NOTE: This function can and will sleep on recovery of other nodes | 723 | * NOTE: This function can and will sleep on recovery of other nodes |
912 | * during cluster locking, just like any other ocfs2 process. | 724 | * during cluster locking, just like any other ocfs2 process. |
913 | */ | 725 | */ |
914 | void ocfs2_complete_recovery(void *data) | 726 | void ocfs2_complete_recovery(struct work_struct *work) |
915 | { | 727 | { |
916 | int ret; | 728 | int ret; |
917 | struct ocfs2_super *osb = data; | 729 | struct ocfs2_journal *journal = |
918 | struct ocfs2_journal *journal = osb->journal; | 730 | container_of(work, struct ocfs2_journal, j_recovery_work); |
731 | struct ocfs2_super *osb = journal->j_osb; | ||
919 | struct ocfs2_dinode *la_dinode, *tl_dinode; | 732 | struct ocfs2_dinode *la_dinode, *tl_dinode; |
920 | struct ocfs2_la_recovery_item *item; | 733 | struct ocfs2_la_recovery_item *item; |
921 | struct list_head *p, *n; | 734 | struct list_head *p, *n; |
@@ -1160,8 +973,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, | |||
1160 | } | 973 | } |
1161 | SET_INODE_JOURNAL(inode); | 974 | SET_INODE_JOURNAL(inode); |
1162 | 975 | ||
1163 | status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, | 976 | status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY); |
1164 | OCFS2_META_LOCK_RECOVERY); | ||
1165 | if (status < 0) { | 977 | if (status < 0) { |
1166 | mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); | 978 | mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); |
1167 | if (status != -ERESTARTSYS) | 979 | if (status != -ERESTARTSYS) |
@@ -1350,7 +1162,7 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb, | |||
1350 | SET_INODE_JOURNAL(inode); | 1162 | SET_INODE_JOURNAL(inode); |
1351 | 1163 | ||
1352 | flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; | 1164 | flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; |
1353 | status = ocfs2_meta_lock_full(inode, NULL, NULL, 1, flags); | 1165 | status = ocfs2_meta_lock_full(inode, NULL, 1, flags); |
1354 | if (status < 0) { | 1166 | if (status < 0) { |
1355 | if (status != -EAGAIN) | 1167 | if (status != -EAGAIN) |
1356 | mlog_errno(status); | 1168 | mlog_errno(status); |
@@ -1433,7 +1245,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, | |||
1433 | } | 1245 | } |
1434 | 1246 | ||
1435 | mutex_lock(&orphan_dir_inode->i_mutex); | 1247 | mutex_lock(&orphan_dir_inode->i_mutex); |
1436 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); | 1248 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, 0); |
1437 | if (status < 0) { | 1249 | if (status < 0) { |
1438 | mlog_errno(status); | 1250 | mlog_errno(status); |
1439 | goto out; | 1251 | goto out; |
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 2f3a6acdac45..e1216364d191 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
@@ -37,7 +37,6 @@ enum ocfs2_journal_state { | |||
37 | 37 | ||
38 | struct ocfs2_super; | 38 | struct ocfs2_super; |
39 | struct ocfs2_dinode; | 39 | struct ocfs2_dinode; |
40 | struct ocfs2_journal_handle; | ||
41 | 40 | ||
42 | struct ocfs2_journal { | 41 | struct ocfs2_journal { |
43 | enum ocfs2_journal_state j_state; /* Journals current state */ | 42 | enum ocfs2_journal_state j_state; /* Journals current state */ |
@@ -133,46 +132,8 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, | |||
133 | spin_unlock(&trans_inc_lock); | 132 | spin_unlock(&trans_inc_lock); |
134 | } | 133 | } |
135 | 134 | ||
136 | extern kmem_cache_t *ocfs2_lock_cache; | ||
137 | |||
138 | struct ocfs2_journal_lock { | ||
139 | struct inode *jl_inode; | ||
140 | struct list_head jl_lock_list; | ||
141 | }; | ||
142 | |||
143 | struct ocfs2_journal_handle { | ||
144 | handle_t *k_handle; /* kernel handle. */ | ||
145 | struct ocfs2_journal *journal; | ||
146 | u32 flags; /* see flags below. */ | ||
147 | int max_buffs; /* Buffs reserved by this handle */ | ||
148 | |||
149 | /* The following two fields are for ocfs2_handle_add_lock */ | ||
150 | int num_locks; | ||
151 | struct list_head locks; /* A bunch of locks to | ||
152 | * release on commit. This | ||
153 | * should be a list_head */ | ||
154 | |||
155 | struct list_head inode_list; | ||
156 | }; | ||
157 | |||
158 | #define OCFS2_HANDLE_STARTED 1 | ||
159 | /* should we sync-commit this handle? */ | ||
160 | #define OCFS2_HANDLE_SYNC 2 | ||
161 | static inline int ocfs2_handle_started(struct ocfs2_journal_handle *handle) | ||
162 | { | ||
163 | return handle->flags & OCFS2_HANDLE_STARTED; | ||
164 | } | ||
165 | |||
166 | static inline void ocfs2_handle_set_sync(struct ocfs2_journal_handle *handle, int sync) | ||
167 | { | ||
168 | if (sync) | ||
169 | handle->flags |= OCFS2_HANDLE_SYNC; | ||
170 | else | ||
171 | handle->flags &= ~OCFS2_HANDLE_SYNC; | ||
172 | } | ||
173 | |||
174 | /* Exported only for the journal struct init code in super.c. Do not call. */ | 135 | /* Exported only for the journal struct init code in super.c. Do not call. */ |
175 | void ocfs2_complete_recovery(void *data); | 136 | void ocfs2_complete_recovery(struct work_struct *work); |
176 | 137 | ||
177 | /* | 138 | /* |
178 | * Journal Control: | 139 | * Journal Control: |
@@ -196,7 +157,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, | |||
196 | void ocfs2_journal_shutdown(struct ocfs2_super *osb); | 157 | void ocfs2_journal_shutdown(struct ocfs2_super *osb); |
197 | int ocfs2_journal_wipe(struct ocfs2_journal *journal, | 158 | int ocfs2_journal_wipe(struct ocfs2_journal *journal, |
198 | int full); | 159 | int full); |
199 | int ocfs2_journal_load(struct ocfs2_journal *journal); | 160 | int ocfs2_journal_load(struct ocfs2_journal *journal, int local); |
200 | int ocfs2_check_journals_nolocks(struct ocfs2_super *osb); | 161 | int ocfs2_check_journals_nolocks(struct ocfs2_super *osb); |
201 | void ocfs2_recovery_thread(struct ocfs2_super *osb, | 162 | void ocfs2_recovery_thread(struct ocfs2_super *osb, |
202 | int node_num); | 163 | int node_num); |
@@ -213,6 +174,9 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
213 | { | 174 | { |
214 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 175 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
215 | 176 | ||
177 | if (ocfs2_mount_local(osb)) | ||
178 | return; | ||
179 | |||
216 | if (!ocfs2_inode_fully_checkpointed(inode)) { | 180 | if (!ocfs2_inode_fully_checkpointed(inode)) { |
217 | /* WARNING: This only kicks off a single | 181 | /* WARNING: This only kicks off a single |
218 | * checkpoint. If someone races you and adds more | 182 | * checkpoint. If someone races you and adds more |
@@ -231,15 +195,14 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
231 | * Transaction Handling: | 195 | * Transaction Handling: |
232 | * Manage the lifetime of a transaction handle. | 196 | * Manage the lifetime of a transaction handle. |
233 | * | 197 | * |
234 | * ocfs2_alloc_handle - Only allocate a handle so we can start putting | ||
235 | * cluster locks on it. To actually change blocks, | ||
236 | * call ocfs2_start_trans with the handle returned | ||
237 | * from this function. You may call ocfs2_commit_trans | ||
238 | * at any time in the lifetime of a handle. | ||
239 | * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of | 198 | * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of |
240 | * the number of blocks that will be changed during | 199 | * the number of blocks that will be changed during |
241 | * this handle. | 200 | * this handle. |
242 | * ocfs2_commit_trans - Complete a handle. | 201 | * ocfs2_commit_trans - Complete a handle. It might return -EIO if |
202 | * the journal was aborted. The majority of paths don't | ||
203 | * check the return value as an error there comes too | ||
204 | * late to do anything (and will be picked up in a | ||
205 | * later transaction). | ||
243 | * ocfs2_extend_trans - Extend a handle by nblocks credits. This may | 206 | * ocfs2_extend_trans - Extend a handle by nblocks credits. This may |
244 | * commit the handle to disk in the process, but will | 207 | * commit the handle to disk in the process, but will |
245 | * not release any locks taken during the transaction. | 208 | * not release any locks taken during the transaction. |
@@ -249,24 +212,16 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
249 | * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. | 212 | * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. |
250 | * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before | 213 | * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before |
251 | * the current handle commits. | 214 | * the current handle commits. |
252 | * ocfs2_handle_add_lock - Sometimes we need to delay lock release | ||
253 | * until after a transaction has been completed. Use | ||
254 | * ocfs2_handle_add_lock to indicate that a lock needs | ||
255 | * to be released at the end of that handle. Locks | ||
256 | * will be released in the order that they are added. | ||
257 | * ocfs2_handle_add_inode - Add a locked inode to a transaction. | ||
258 | */ | 215 | */ |
259 | 216 | ||
260 | /* You must always start_trans with a number of buffs > 0, but it's | 217 | /* You must always start_trans with a number of buffs > 0, but it's |
261 | * perfectly legal to go through an entire transaction without having | 218 | * perfectly legal to go through an entire transaction without having |
262 | * dirtied any buffers. */ | 219 | * dirtied any buffers. */ |
263 | struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb); | 220 | handle_t *ocfs2_start_trans(struct ocfs2_super *osb, |
264 | struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | ||
265 | struct ocfs2_journal_handle *handle, | ||
266 | int max_buffs); | 221 | int max_buffs); |
267 | void ocfs2_commit_trans(struct ocfs2_journal_handle *handle); | 222 | int ocfs2_commit_trans(struct ocfs2_super *osb, |
268 | int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | 223 | handle_t *handle); |
269 | int nblocks); | 224 | int ocfs2_extend_trans(handle_t *handle, int nblocks); |
270 | 225 | ||
271 | /* | 226 | /* |
272 | * Create access is for when we get a newly created buffer and we're | 227 | * Create access is for when we get a newly created buffer and we're |
@@ -283,7 +238,7 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | |||
283 | #define OCFS2_JOURNAL_ACCESS_WRITE 1 | 238 | #define OCFS2_JOURNAL_ACCESS_WRITE 1 |
284 | #define OCFS2_JOURNAL_ACCESS_UNDO 2 | 239 | #define OCFS2_JOURNAL_ACCESS_UNDO 2 |
285 | 240 | ||
286 | int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | 241 | int ocfs2_journal_access(handle_t *handle, |
287 | struct inode *inode, | 242 | struct inode *inode, |
288 | struct buffer_head *bh, | 243 | struct buffer_head *bh, |
289 | int type); | 244 | int type); |
@@ -306,18 +261,10 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
306 | * <modify the bh> | 261 | * <modify the bh> |
307 | * ocfs2_journal_dirty(handle, bh); | 262 | * ocfs2_journal_dirty(handle, bh); |
308 | */ | 263 | */ |
309 | int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, | 264 | int ocfs2_journal_dirty(handle_t *handle, |
310 | struct buffer_head *bh); | 265 | struct buffer_head *bh); |
311 | int ocfs2_journal_dirty_data(handle_t *handle, | 266 | int ocfs2_journal_dirty_data(handle_t *handle, |
312 | struct buffer_head *bh); | 267 | struct buffer_head *bh); |
313 | int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle, | ||
314 | struct inode *inode); | ||
315 | /* | ||
316 | * Use this to protect from other processes reading buffer state while | ||
317 | * it's in flight. | ||
318 | */ | ||
319 | void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle, | ||
320 | struct inode *inode); | ||
321 | 268 | ||
322 | /* | 269 | /* |
323 | * Credit Macros: | 270 | * Credit Macros: |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 1f17a4d08287..4dedd9789108 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -58,19 +58,18 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, | |||
58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); | 58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); |
59 | 59 | ||
60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
61 | struct ocfs2_journal_handle *handle, | 61 | handle_t *handle, |
62 | struct ocfs2_dinode *alloc, | 62 | struct ocfs2_dinode *alloc, |
63 | struct inode *main_bm_inode, | 63 | struct inode *main_bm_inode, |
64 | struct buffer_head *main_bm_bh); | 64 | struct buffer_head *main_bm_bh); |
65 | 65 | ||
66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
67 | struct ocfs2_journal_handle *handle, | ||
68 | struct ocfs2_alloc_context **ac, | 67 | struct ocfs2_alloc_context **ac, |
69 | struct inode **bitmap_inode, | 68 | struct inode **bitmap_inode, |
70 | struct buffer_head **bitmap_bh); | 69 | struct buffer_head **bitmap_bh); |
71 | 70 | ||
72 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 71 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
73 | struct ocfs2_journal_handle *handle, | 72 | handle_t *handle, |
74 | struct ocfs2_alloc_context *ac); | 73 | struct ocfs2_alloc_context *ac); |
75 | 74 | ||
76 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | 75 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, |
@@ -196,7 +195,7 @@ bail: | |||
196 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | 195 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) |
197 | { | 196 | { |
198 | int status; | 197 | int status; |
199 | struct ocfs2_journal_handle *handle = NULL; | 198 | handle_t *handle; |
200 | struct inode *local_alloc_inode = NULL; | 199 | struct inode *local_alloc_inode = NULL; |
201 | struct buffer_head *bh = NULL; | 200 | struct buffer_head *bh = NULL; |
202 | struct buffer_head *main_bm_bh = NULL; | 201 | struct buffer_head *main_bm_bh = NULL; |
@@ -207,7 +206,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
207 | mlog_entry_void(); | 206 | mlog_entry_void(); |
208 | 207 | ||
209 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) | 208 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) |
210 | goto bail; | 209 | goto out; |
211 | 210 | ||
212 | local_alloc_inode = | 211 | local_alloc_inode = |
213 | ocfs2_get_system_file_inode(osb, | 212 | ocfs2_get_system_file_inode(osb, |
@@ -216,40 +215,34 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
216 | if (!local_alloc_inode) { | 215 | if (!local_alloc_inode) { |
217 | status = -ENOENT; | 216 | status = -ENOENT; |
218 | mlog_errno(status); | 217 | mlog_errno(status); |
219 | goto bail; | 218 | goto out; |
220 | } | 219 | } |
221 | 220 | ||
222 | osb->local_alloc_state = OCFS2_LA_DISABLED; | 221 | osb->local_alloc_state = OCFS2_LA_DISABLED; |
223 | 222 | ||
224 | handle = ocfs2_alloc_handle(osb); | ||
225 | if (!handle) { | ||
226 | status = -ENOMEM; | ||
227 | mlog_errno(status); | ||
228 | goto bail; | ||
229 | } | ||
230 | |||
231 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 223 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
232 | GLOBAL_BITMAP_SYSTEM_INODE, | 224 | GLOBAL_BITMAP_SYSTEM_INODE, |
233 | OCFS2_INVALID_SLOT); | 225 | OCFS2_INVALID_SLOT); |
234 | if (!main_bm_inode) { | 226 | if (!main_bm_inode) { |
235 | status = -EINVAL; | 227 | status = -EINVAL; |
236 | mlog_errno(status); | 228 | mlog_errno(status); |
237 | goto bail; | 229 | goto out; |
238 | } | 230 | } |
239 | 231 | ||
240 | ocfs2_handle_add_inode(handle, main_bm_inode); | 232 | mutex_lock(&main_bm_inode->i_mutex); |
241 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 233 | |
234 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
242 | if (status < 0) { | 235 | if (status < 0) { |
243 | mlog_errno(status); | 236 | mlog_errno(status); |
244 | goto bail; | 237 | goto out_mutex; |
245 | } | 238 | } |
246 | 239 | ||
247 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ | 240 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ |
248 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 241 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
249 | if (IS_ERR(handle)) { | 242 | if (IS_ERR(handle)) { |
250 | mlog_errno(PTR_ERR(handle)); | 243 | mlog_errno(PTR_ERR(handle)); |
251 | handle = NULL; | 244 | handle = NULL; |
252 | goto bail; | 245 | goto out_unlock; |
253 | } | 246 | } |
254 | 247 | ||
255 | bh = osb->local_alloc_bh; | 248 | bh = osb->local_alloc_bh; |
@@ -258,7 +251,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
258 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); | 251 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); |
259 | if (!alloc_copy) { | 252 | if (!alloc_copy) { |
260 | status = -ENOMEM; | 253 | status = -ENOMEM; |
261 | goto bail; | 254 | goto out_commit; |
262 | } | 255 | } |
263 | memcpy(alloc_copy, alloc, bh->b_size); | 256 | memcpy(alloc_copy, alloc, bh->b_size); |
264 | 257 | ||
@@ -266,7 +259,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
266 | OCFS2_JOURNAL_ACCESS_WRITE); | 259 | OCFS2_JOURNAL_ACCESS_WRITE); |
267 | if (status < 0) { | 260 | if (status < 0) { |
268 | mlog_errno(status); | 261 | mlog_errno(status); |
269 | goto bail; | 262 | goto out_commit; |
270 | } | 263 | } |
271 | 264 | ||
272 | ocfs2_clear_local_alloc(alloc); | 265 | ocfs2_clear_local_alloc(alloc); |
@@ -274,7 +267,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
274 | status = ocfs2_journal_dirty(handle, bh); | 267 | status = ocfs2_journal_dirty(handle, bh); |
275 | if (status < 0) { | 268 | if (status < 0) { |
276 | mlog_errno(status); | 269 | mlog_errno(status); |
277 | goto bail; | 270 | goto out_commit; |
278 | } | 271 | } |
279 | 272 | ||
280 | brelse(bh); | 273 | brelse(bh); |
@@ -286,16 +279,20 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
286 | if (status < 0) | 279 | if (status < 0) |
287 | mlog_errno(status); | 280 | mlog_errno(status); |
288 | 281 | ||
289 | bail: | 282 | out_commit: |
290 | if (handle) | 283 | ocfs2_commit_trans(osb, handle); |
291 | ocfs2_commit_trans(handle); | ||
292 | 284 | ||
285 | out_unlock: | ||
293 | if (main_bm_bh) | 286 | if (main_bm_bh) |
294 | brelse(main_bm_bh); | 287 | brelse(main_bm_bh); |
295 | 288 | ||
296 | if (main_bm_inode) | 289 | ocfs2_meta_unlock(main_bm_inode, 1); |
297 | iput(main_bm_inode); | ||
298 | 290 | ||
291 | out_mutex: | ||
292 | mutex_unlock(&main_bm_inode->i_mutex); | ||
293 | iput(main_bm_inode); | ||
294 | |||
295 | out: | ||
299 | if (local_alloc_inode) | 296 | if (local_alloc_inode) |
300 | iput(local_alloc_inode); | 297 | iput(local_alloc_inode); |
301 | 298 | ||
@@ -385,61 +382,59 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb, | |||
385 | struct ocfs2_dinode *alloc) | 382 | struct ocfs2_dinode *alloc) |
386 | { | 383 | { |
387 | int status; | 384 | int status; |
388 | struct ocfs2_journal_handle *handle = NULL; | 385 | handle_t *handle; |
389 | struct buffer_head *main_bm_bh = NULL; | 386 | struct buffer_head *main_bm_bh = NULL; |
390 | struct inode *main_bm_inode = NULL; | 387 | struct inode *main_bm_inode; |
391 | 388 | ||
392 | mlog_entry_void(); | 389 | mlog_entry_void(); |
393 | 390 | ||
394 | handle = ocfs2_alloc_handle(osb); | ||
395 | if (!handle) { | ||
396 | status = -ENOMEM; | ||
397 | mlog_errno(status); | ||
398 | goto bail; | ||
399 | } | ||
400 | |||
401 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 391 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
402 | GLOBAL_BITMAP_SYSTEM_INODE, | 392 | GLOBAL_BITMAP_SYSTEM_INODE, |
403 | OCFS2_INVALID_SLOT); | 393 | OCFS2_INVALID_SLOT); |
404 | if (!main_bm_inode) { | 394 | if (!main_bm_inode) { |
405 | status = -EINVAL; | 395 | status = -EINVAL; |
406 | mlog_errno(status); | 396 | mlog_errno(status); |
407 | goto bail; | 397 | goto out; |
408 | } | 398 | } |
409 | 399 | ||
410 | ocfs2_handle_add_inode(handle, main_bm_inode); | 400 | mutex_lock(&main_bm_inode->i_mutex); |
411 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 401 | |
402 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
412 | if (status < 0) { | 403 | if (status < 0) { |
413 | mlog_errno(status); | 404 | mlog_errno(status); |
414 | goto bail; | 405 | goto out_mutex; |
415 | } | 406 | } |
416 | 407 | ||
417 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 408 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
418 | if (IS_ERR(handle)) { | 409 | if (IS_ERR(handle)) { |
419 | status = PTR_ERR(handle); | 410 | status = PTR_ERR(handle); |
420 | handle = NULL; | 411 | handle = NULL; |
421 | mlog_errno(status); | 412 | mlog_errno(status); |
422 | goto bail; | 413 | goto out_unlock; |
423 | } | 414 | } |
424 | 415 | ||
425 | /* we want the bitmap change to be recorded on disk asap */ | 416 | /* we want the bitmap change to be recorded on disk asap */ |
426 | ocfs2_handle_set_sync(handle, 1); | 417 | handle->h_sync = 1; |
427 | 418 | ||
428 | status = ocfs2_sync_local_to_main(osb, handle, alloc, | 419 | status = ocfs2_sync_local_to_main(osb, handle, alloc, |
429 | main_bm_inode, main_bm_bh); | 420 | main_bm_inode, main_bm_bh); |
430 | if (status < 0) | 421 | if (status < 0) |
431 | mlog_errno(status); | 422 | mlog_errno(status); |
432 | 423 | ||
433 | bail: | 424 | ocfs2_commit_trans(osb, handle); |
434 | if (handle) | 425 | |
435 | ocfs2_commit_trans(handle); | 426 | out_unlock: |
427 | ocfs2_meta_unlock(main_bm_inode, 1); | ||
428 | |||
429 | out_mutex: | ||
430 | mutex_unlock(&main_bm_inode->i_mutex); | ||
436 | 431 | ||
437 | if (main_bm_bh) | 432 | if (main_bm_bh) |
438 | brelse(main_bm_bh); | 433 | brelse(main_bm_bh); |
439 | 434 | ||
440 | if (main_bm_inode) | 435 | iput(main_bm_inode); |
441 | iput(main_bm_inode); | ||
442 | 436 | ||
437 | out: | ||
443 | mlog_exit(status); | 438 | mlog_exit(status); |
444 | return status; | 439 | return status; |
445 | } | 440 | } |
@@ -452,7 +447,6 @@ bail: | |||
452 | * our own in order to shift windows. | 447 | * our own in order to shift windows. |
453 | */ | 448 | */ |
454 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | 449 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, |
455 | struct ocfs2_journal_handle *passed_handle, | ||
456 | u32 bits_wanted, | 450 | u32 bits_wanted, |
457 | struct ocfs2_alloc_context *ac) | 451 | struct ocfs2_alloc_context *ac) |
458 | { | 452 | { |
@@ -463,9 +457,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
463 | 457 | ||
464 | mlog_entry_void(); | 458 | mlog_entry_void(); |
465 | 459 | ||
466 | BUG_ON(!passed_handle); | ||
467 | BUG_ON(!ac); | 460 | BUG_ON(!ac); |
468 | BUG_ON(passed_handle->flags & OCFS2_HANDLE_STARTED); | ||
469 | 461 | ||
470 | local_alloc_inode = | 462 | local_alloc_inode = |
471 | ocfs2_get_system_file_inode(osb, | 463 | ocfs2_get_system_file_inode(osb, |
@@ -476,7 +468,11 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
476 | mlog_errno(status); | 468 | mlog_errno(status); |
477 | goto bail; | 469 | goto bail; |
478 | } | 470 | } |
479 | ocfs2_handle_add_inode(passed_handle, local_alloc_inode); | 471 | |
472 | mutex_lock(&local_alloc_inode->i_mutex); | ||
473 | |||
474 | ac->ac_inode = local_alloc_inode; | ||
475 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
480 | 476 | ||
481 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { | 477 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { |
482 | status = -ENOSPC; | 478 | status = -ENOSPC; |
@@ -515,21 +511,17 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
515 | } | 511 | } |
516 | } | 512 | } |
517 | 513 | ||
518 | ac->ac_inode = igrab(local_alloc_inode); | ||
519 | get_bh(osb->local_alloc_bh); | 514 | get_bh(osb->local_alloc_bh); |
520 | ac->ac_bh = osb->local_alloc_bh; | 515 | ac->ac_bh = osb->local_alloc_bh; |
521 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
522 | status = 0; | 516 | status = 0; |
523 | bail: | 517 | bail: |
524 | if (local_alloc_inode) | ||
525 | iput(local_alloc_inode); | ||
526 | 518 | ||
527 | mlog_exit(status); | 519 | mlog_exit(status); |
528 | return status; | 520 | return status; |
529 | } | 521 | } |
530 | 522 | ||
531 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | 523 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, |
532 | struct ocfs2_journal_handle *handle, | 524 | handle_t *handle, |
533 | struct ocfs2_alloc_context *ac, | 525 | struct ocfs2_alloc_context *ac, |
534 | u32 min_bits, | 526 | u32 min_bits, |
535 | u32 *bit_off, | 527 | u32 *bit_off, |
@@ -707,7 +699,7 @@ static void ocfs2_verify_zero_bits(unsigned long *bitmap, | |||
707 | * passed is used for caching. | 699 | * passed is used for caching. |
708 | */ | 700 | */ |
709 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 701 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
710 | struct ocfs2_journal_handle *handle, | 702 | handle_t *handle, |
711 | struct ocfs2_dinode *alloc, | 703 | struct ocfs2_dinode *alloc, |
712 | struct inode *main_bm_inode, | 704 | struct inode *main_bm_inode, |
713 | struct buffer_head *main_bm_bh) | 705 | struct buffer_head *main_bm_bh) |
@@ -778,21 +770,19 @@ bail: | |||
778 | } | 770 | } |
779 | 771 | ||
780 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 772 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
781 | struct ocfs2_journal_handle *handle, | ||
782 | struct ocfs2_alloc_context **ac, | 773 | struct ocfs2_alloc_context **ac, |
783 | struct inode **bitmap_inode, | 774 | struct inode **bitmap_inode, |
784 | struct buffer_head **bitmap_bh) | 775 | struct buffer_head **bitmap_bh) |
785 | { | 776 | { |
786 | int status; | 777 | int status; |
787 | 778 | ||
788 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 779 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
789 | if (!(*ac)) { | 780 | if (!(*ac)) { |
790 | status = -ENOMEM; | 781 | status = -ENOMEM; |
791 | mlog_errno(status); | 782 | mlog_errno(status); |
792 | goto bail; | 783 | goto bail; |
793 | } | 784 | } |
794 | 785 | ||
795 | (*ac)->ac_handle = handle; | ||
796 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); | 786 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); |
797 | 787 | ||
798 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); | 788 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); |
@@ -821,7 +811,7 @@ bail: | |||
821 | * pass it the bitmap lock in lock_bh if you have it. | 811 | * pass it the bitmap lock in lock_bh if you have it. |
822 | */ | 812 | */ |
823 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 813 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
824 | struct ocfs2_journal_handle *handle, | 814 | handle_t *handle, |
825 | struct ocfs2_alloc_context *ac) | 815 | struct ocfs2_alloc_context *ac) |
826 | { | 816 | { |
827 | int status = 0; | 817 | int status = 0; |
@@ -888,23 +878,15 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
888 | int status = 0; | 878 | int status = 0; |
889 | struct buffer_head *main_bm_bh = NULL; | 879 | struct buffer_head *main_bm_bh = NULL; |
890 | struct inode *main_bm_inode = NULL; | 880 | struct inode *main_bm_inode = NULL; |
891 | struct ocfs2_journal_handle *handle = NULL; | 881 | handle_t *handle = NULL; |
892 | struct ocfs2_dinode *alloc; | 882 | struct ocfs2_dinode *alloc; |
893 | struct ocfs2_dinode *alloc_copy = NULL; | 883 | struct ocfs2_dinode *alloc_copy = NULL; |
894 | struct ocfs2_alloc_context *ac = NULL; | 884 | struct ocfs2_alloc_context *ac = NULL; |
895 | 885 | ||
896 | mlog_entry_void(); | 886 | mlog_entry_void(); |
897 | 887 | ||
898 | handle = ocfs2_alloc_handle(osb); | ||
899 | if (!handle) { | ||
900 | status = -ENOMEM; | ||
901 | mlog_errno(status); | ||
902 | goto bail; | ||
903 | } | ||
904 | |||
905 | /* This will lock the main bitmap for us. */ | 888 | /* This will lock the main bitmap for us. */ |
906 | status = ocfs2_local_alloc_reserve_for_window(osb, | 889 | status = ocfs2_local_alloc_reserve_for_window(osb, |
907 | handle, | ||
908 | &ac, | 890 | &ac, |
909 | &main_bm_inode, | 891 | &main_bm_inode, |
910 | &main_bm_bh); | 892 | &main_bm_bh); |
@@ -914,7 +896,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
914 | goto bail; | 896 | goto bail; |
915 | } | 897 | } |
916 | 898 | ||
917 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 899 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
918 | if (IS_ERR(handle)) { | 900 | if (IS_ERR(handle)) { |
919 | status = PTR_ERR(handle); | 901 | status = PTR_ERR(handle); |
920 | handle = NULL; | 902 | handle = NULL; |
@@ -972,7 +954,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
972 | status = 0; | 954 | status = 0; |
973 | bail: | 955 | bail: |
974 | if (handle) | 956 | if (handle) |
975 | ocfs2_commit_trans(handle); | 957 | ocfs2_commit_trans(osb, handle); |
976 | 958 | ||
977 | if (main_bm_bh) | 959 | if (main_bm_bh) |
978 | brelse(main_bm_bh); | 960 | brelse(main_bm_bh); |
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h index 30f88ce14e46..385a10152f9c 100644 --- a/fs/ocfs2/localalloc.h +++ b/fs/ocfs2/localalloc.h | |||
@@ -42,12 +42,11 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, | |||
42 | 42 | ||
43 | struct ocfs2_alloc_context; | 43 | struct ocfs2_alloc_context; |
44 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | 44 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, |
45 | struct ocfs2_journal_handle *passed_handle, | ||
46 | u32 bits_wanted, | 45 | u32 bits_wanted, |
47 | struct ocfs2_alloc_context *ac); | 46 | struct ocfs2_alloc_context *ac); |
48 | 47 | ||
49 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | 48 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, |
50 | struct ocfs2_journal_handle *handle, | 49 | handle_t *handle, |
51 | struct ocfs2_alloc_context *ac, | 50 | struct ocfs2_alloc_context *ac, |
52 | u32 min_bits, | 51 | u32 min_bits, |
53 | u32 *bit_off, | 52 | u32 *bit_off, |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index 83934e33e5b0..51b020447683 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
@@ -82,16 +82,27 @@ static struct vm_operations_struct ocfs2_file_vm_ops = { | |||
82 | 82 | ||
83 | int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) | 83 | int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) |
84 | { | 84 | { |
85 | int ret = 0, lock_level = 0; | ||
86 | struct ocfs2_super *osb = OCFS2_SB(file->f_dentry->d_inode->i_sb); | ||
87 | |||
85 | /* We don't want to support shared writable mappings yet. */ | 88 | /* We don't want to support shared writable mappings yet. */ |
86 | if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) | 89 | if (!ocfs2_mount_local(osb) && |
87 | && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { | 90 | ((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) && |
91 | ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { | ||
88 | mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags); | 92 | mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags); |
89 | /* This is -EINVAL because generic_file_readonly_mmap | 93 | /* This is -EINVAL because generic_file_readonly_mmap |
90 | * returns it in a similar situation. */ | 94 | * returns it in a similar situation. */ |
91 | return -EINVAL; | 95 | return -EINVAL; |
92 | } | 96 | } |
93 | 97 | ||
94 | file_accessed(file); | 98 | ret = ocfs2_meta_lock_atime(file->f_dentry->d_inode, |
99 | file->f_vfsmnt, &lock_level); | ||
100 | if (ret < 0) { | ||
101 | mlog_errno(ret); | ||
102 | goto out; | ||
103 | } | ||
104 | ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level); | ||
105 | out: | ||
95 | vma->vm_ops = &ocfs2_file_vm_ops; | 106 | vma->vm_ops = &ocfs2_file_vm_ops; |
96 | return 0; | 107 | return 0; |
97 | } | 108 | } |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a57b751d4f40..9637039c2633 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -75,12 +75,12 @@ static int inline ocfs2_search_dirblock(struct buffer_head *bh, | |||
75 | unsigned long offset, | 75 | unsigned long offset, |
76 | struct ocfs2_dir_entry **res_dir); | 76 | struct ocfs2_dir_entry **res_dir); |
77 | 77 | ||
78 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 78 | static int ocfs2_delete_entry(handle_t *handle, |
79 | struct inode *dir, | 79 | struct inode *dir, |
80 | struct ocfs2_dir_entry *de_del, | 80 | struct ocfs2_dir_entry *de_del, |
81 | struct buffer_head *bh); | 81 | struct buffer_head *bh); |
82 | 82 | ||
83 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 83 | static int __ocfs2_add_entry(handle_t *handle, |
84 | struct inode *dir, | 84 | struct inode *dir, |
85 | const char *name, int namelen, | 85 | const char *name, int namelen, |
86 | struct inode *inode, u64 blkno, | 86 | struct inode *inode, u64 blkno, |
@@ -93,43 +93,37 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
93 | dev_t dev, | 93 | dev_t dev, |
94 | struct buffer_head **new_fe_bh, | 94 | struct buffer_head **new_fe_bh, |
95 | struct buffer_head *parent_fe_bh, | 95 | struct buffer_head *parent_fe_bh, |
96 | struct ocfs2_journal_handle *handle, | 96 | handle_t *handle, |
97 | struct inode **ret_inode, | 97 | struct inode **ret_inode, |
98 | struct ocfs2_alloc_context *inode_ac); | 98 | struct ocfs2_alloc_context *inode_ac); |
99 | 99 | ||
100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
101 | struct ocfs2_journal_handle *handle, | 101 | handle_t *handle, |
102 | struct inode *parent, | 102 | struct inode *parent, |
103 | struct inode *inode, | 103 | struct inode *inode, |
104 | struct buffer_head *fe_bh, | 104 | struct buffer_head *fe_bh, |
105 | struct ocfs2_alloc_context *data_ac); | 105 | struct ocfs2_alloc_context *data_ac); |
106 | 106 | ||
107 | static int ocfs2_double_lock(struct ocfs2_super *osb, | ||
108 | struct ocfs2_journal_handle *handle, | ||
109 | struct buffer_head **bh1, | ||
110 | struct inode *inode1, | ||
111 | struct buffer_head **bh2, | ||
112 | struct inode *inode2); | ||
113 | |||
114 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 107 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
115 | struct ocfs2_journal_handle *handle, | 108 | struct inode **ret_orphan_dir, |
116 | struct inode *inode, | 109 | struct inode *inode, |
117 | char *name, | 110 | char *name, |
118 | struct buffer_head **de_bh); | 111 | struct buffer_head **de_bh); |
119 | 112 | ||
120 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 113 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
121 | struct ocfs2_journal_handle *handle, | 114 | handle_t *handle, |
122 | struct inode *inode, | 115 | struct inode *inode, |
123 | struct ocfs2_dinode *fe, | 116 | struct ocfs2_dinode *fe, |
124 | char *name, | 117 | char *name, |
125 | struct buffer_head *de_bh); | 118 | struct buffer_head *de_bh, |
119 | struct inode *orphan_dir_inode); | ||
126 | 120 | ||
127 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 121 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
128 | struct ocfs2_journal_handle *handle, | 122 | handle_t *handle, |
129 | struct inode *inode, | 123 | struct inode *inode, |
130 | const char *symname); | 124 | const char *symname); |
131 | 125 | ||
132 | static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 126 | static inline int ocfs2_add_entry(handle_t *handle, |
133 | struct dentry *dentry, | 127 | struct dentry *dentry, |
134 | struct inode *inode, u64 blkno, | 128 | struct inode *inode, u64 blkno, |
135 | struct buffer_head *parent_fe_bh, | 129 | struct buffer_head *parent_fe_bh, |
@@ -165,7 +159,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
165 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, | 159 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, |
166 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); | 160 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); |
167 | 161 | ||
168 | status = ocfs2_meta_lock(dir, NULL, NULL, 0); | 162 | status = ocfs2_meta_lock(dir, NULL, 0); |
169 | if (status < 0) { | 163 | if (status < 0) { |
170 | if (status != -ENOENT) | 164 | if (status != -ENOENT) |
171 | mlog_errno(status); | 165 | mlog_errno(status); |
@@ -242,7 +236,7 @@ bail: | |||
242 | } | 236 | } |
243 | 237 | ||
244 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 238 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
245 | struct ocfs2_journal_handle *handle, | 239 | handle_t *handle, |
246 | struct inode *parent, | 240 | struct inode *parent, |
247 | struct inode *inode, | 241 | struct inode *inode, |
248 | struct buffer_head *fe_bh, | 242 | struct buffer_head *fe_bh, |
@@ -317,7 +311,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
317 | { | 311 | { |
318 | int status = 0; | 312 | int status = 0; |
319 | struct buffer_head *parent_fe_bh = NULL; | 313 | struct buffer_head *parent_fe_bh = NULL; |
320 | struct ocfs2_journal_handle *handle = NULL; | 314 | handle_t *handle = NULL; |
321 | struct ocfs2_super *osb; | 315 | struct ocfs2_super *osb; |
322 | struct ocfs2_dinode *dirfe; | 316 | struct ocfs2_dinode *dirfe; |
323 | struct buffer_head *new_fe_bh = NULL; | 317 | struct buffer_head *new_fe_bh = NULL; |
@@ -333,18 +327,11 @@ static int ocfs2_mknod(struct inode *dir, | |||
333 | /* get our super block */ | 327 | /* get our super block */ |
334 | osb = OCFS2_SB(dir->i_sb); | 328 | osb = OCFS2_SB(dir->i_sb); |
335 | 329 | ||
336 | handle = ocfs2_alloc_handle(osb); | 330 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
337 | if (handle == NULL) { | ||
338 | status = -ENOMEM; | ||
339 | mlog_errno(status); | ||
340 | goto leave; | ||
341 | } | ||
342 | |||
343 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | ||
344 | if (status < 0) { | 331 | if (status < 0) { |
345 | if (status != -ENOENT) | 332 | if (status != -ENOENT) |
346 | mlog_errno(status); | 333 | mlog_errno(status); |
347 | goto leave; | 334 | return status; |
348 | } | 335 | } |
349 | 336 | ||
350 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { | 337 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { |
@@ -374,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
374 | } | 361 | } |
375 | 362 | ||
376 | /* reserve an inode spot */ | 363 | /* reserve an inode spot */ |
377 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 364 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
378 | if (status < 0) { | 365 | if (status < 0) { |
379 | if (status != -ENOSPC) | 366 | if (status != -ENOSPC) |
380 | mlog_errno(status); | 367 | mlog_errno(status); |
@@ -384,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
384 | /* are we making a directory? If so, reserve a cluster for his | 371 | /* are we making a directory? If so, reserve a cluster for his |
385 | * 1st extent. */ | 372 | * 1st extent. */ |
386 | if (S_ISDIR(mode)) { | 373 | if (S_ISDIR(mode)) { |
387 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 374 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
388 | if (status < 0) { | 375 | if (status < 0) { |
389 | if (status != -ENOSPC) | 376 | if (status != -ENOSPC) |
390 | mlog_errno(status); | 377 | mlog_errno(status); |
@@ -392,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
392 | } | 379 | } |
393 | } | 380 | } |
394 | 381 | ||
395 | handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS); | 382 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS); |
396 | if (IS_ERR(handle)) { | 383 | if (IS_ERR(handle)) { |
397 | status = PTR_ERR(handle); | 384 | status = PTR_ERR(handle); |
398 | handle = NULL; | 385 | handle = NULL; |
@@ -453,7 +440,9 @@ static int ocfs2_mknod(struct inode *dir, | |||
453 | status = 0; | 440 | status = 0; |
454 | leave: | 441 | leave: |
455 | if (handle) | 442 | if (handle) |
456 | ocfs2_commit_trans(handle); | 443 | ocfs2_commit_trans(osb, handle); |
444 | |||
445 | ocfs2_meta_unlock(dir, 1); | ||
457 | 446 | ||
458 | if (status == -ENOSPC) | 447 | if (status == -ENOSPC) |
459 | mlog(0, "Disk is full\n"); | 448 | mlog(0, "Disk is full\n"); |
@@ -487,7 +476,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
487 | dev_t dev, | 476 | dev_t dev, |
488 | struct buffer_head **new_fe_bh, | 477 | struct buffer_head **new_fe_bh, |
489 | struct buffer_head *parent_fe_bh, | 478 | struct buffer_head *parent_fe_bh, |
490 | struct ocfs2_journal_handle *handle, | 479 | handle_t *handle, |
491 | struct inode **ret_inode, | 480 | struct inode **ret_inode, |
492 | struct ocfs2_alloc_context *inode_ac) | 481 | struct ocfs2_alloc_context *inode_ac) |
493 | { | 482 | { |
@@ -598,9 +587,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
598 | } | 587 | } |
599 | 588 | ||
600 | ocfs2_inode_set_new(osb, inode); | 589 | ocfs2_inode_set_new(osb, inode); |
601 | status = ocfs2_create_new_inode_locks(inode); | 590 | if (!ocfs2_mount_local(osb)) { |
602 | if (status < 0) | 591 | status = ocfs2_create_new_inode_locks(inode); |
603 | mlog_errno(status); | 592 | if (status < 0) |
593 | mlog_errno(status); | ||
594 | } | ||
604 | 595 | ||
605 | status = 0; /* error in ocfs2_create_new_inode_locks is not | 596 | status = 0; /* error in ocfs2_create_new_inode_locks is not |
606 | * critical */ | 597 | * critical */ |
@@ -653,7 +644,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
653 | struct inode *dir, | 644 | struct inode *dir, |
654 | struct dentry *dentry) | 645 | struct dentry *dentry) |
655 | { | 646 | { |
656 | struct ocfs2_journal_handle *handle = NULL; | 647 | handle_t *handle; |
657 | struct inode *inode = old_dentry->d_inode; | 648 | struct inode *inode = old_dentry->d_inode; |
658 | int err; | 649 | int err; |
659 | struct buffer_head *fe_bh = NULL; | 650 | struct buffer_head *fe_bh = NULL; |
@@ -666,68 +657,60 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
666 | old_dentry->d_name.len, old_dentry->d_name.name, | 657 | old_dentry->d_name.len, old_dentry->d_name.name, |
667 | dentry->d_name.len, dentry->d_name.name); | 658 | dentry->d_name.len, dentry->d_name.name); |
668 | 659 | ||
669 | if (S_ISDIR(inode->i_mode)) { | 660 | if (S_ISDIR(inode->i_mode)) |
670 | err = -EPERM; | 661 | return -EPERM; |
671 | goto bail; | ||
672 | } | ||
673 | |||
674 | handle = ocfs2_alloc_handle(osb); | ||
675 | if (handle == NULL) { | ||
676 | err = -ENOMEM; | ||
677 | goto bail; | ||
678 | } | ||
679 | 662 | ||
680 | err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 663 | err = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
681 | if (err < 0) { | 664 | if (err < 0) { |
682 | if (err != -ENOENT) | 665 | if (err != -ENOENT) |
683 | mlog_errno(err); | 666 | mlog_errno(err); |
684 | goto bail; | 667 | return err; |
685 | } | 668 | } |
686 | 669 | ||
687 | if (!dir->i_nlink) { | 670 | if (!dir->i_nlink) { |
688 | err = -ENOENT; | 671 | err = -ENOENT; |
689 | goto bail; | 672 | goto out; |
690 | } | 673 | } |
691 | 674 | ||
692 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 675 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
693 | dentry->d_name.len); | 676 | dentry->d_name.len); |
694 | if (err) | 677 | if (err) |
695 | goto bail; | 678 | goto out; |
696 | 679 | ||
697 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, | 680 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, |
698 | dentry->d_name.name, | 681 | dentry->d_name.name, |
699 | dentry->d_name.len, &de_bh); | 682 | dentry->d_name.len, &de_bh); |
700 | if (err < 0) { | 683 | if (err < 0) { |
701 | mlog_errno(err); | 684 | mlog_errno(err); |
702 | goto bail; | 685 | goto out; |
703 | } | 686 | } |
704 | 687 | ||
705 | err = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 688 | err = ocfs2_meta_lock(inode, &fe_bh, 1); |
706 | if (err < 0) { | 689 | if (err < 0) { |
707 | if (err != -ENOENT) | 690 | if (err != -ENOENT) |
708 | mlog_errno(err); | 691 | mlog_errno(err); |
709 | goto bail; | 692 | goto out; |
710 | } | 693 | } |
711 | 694 | ||
712 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 695 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
713 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { | 696 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { |
714 | err = -EMLINK; | 697 | err = -EMLINK; |
715 | goto bail; | 698 | goto out_unlock_inode; |
716 | } | 699 | } |
717 | 700 | ||
718 | handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS); | 701 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); |
719 | if (IS_ERR(handle)) { | 702 | if (IS_ERR(handle)) { |
720 | err = PTR_ERR(handle); | 703 | err = PTR_ERR(handle); |
721 | handle = NULL; | 704 | handle = NULL; |
722 | mlog_errno(err); | 705 | mlog_errno(err); |
723 | goto bail; | 706 | goto out_unlock_inode; |
724 | } | 707 | } |
725 | 708 | ||
726 | err = ocfs2_journal_access(handle, inode, fe_bh, | 709 | err = ocfs2_journal_access(handle, inode, fe_bh, |
727 | OCFS2_JOURNAL_ACCESS_WRITE); | 710 | OCFS2_JOURNAL_ACCESS_WRITE); |
728 | if (err < 0) { | 711 | if (err < 0) { |
729 | mlog_errno(err); | 712 | mlog_errno(err); |
730 | goto bail; | 713 | goto out_commit; |
731 | } | 714 | } |
732 | 715 | ||
733 | inc_nlink(inode); | 716 | inc_nlink(inode); |
@@ -741,7 +724,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
741 | le16_add_cpu(&fe->i_links_count, -1); | 724 | le16_add_cpu(&fe->i_links_count, -1); |
742 | drop_nlink(inode); | 725 | drop_nlink(inode); |
743 | mlog_errno(err); | 726 | mlog_errno(err); |
744 | goto bail; | 727 | goto out_commit; |
745 | } | 728 | } |
746 | 729 | ||
747 | err = ocfs2_add_entry(handle, dentry, inode, | 730 | err = ocfs2_add_entry(handle, dentry, inode, |
@@ -751,21 +734,27 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
751 | le16_add_cpu(&fe->i_links_count, -1); | 734 | le16_add_cpu(&fe->i_links_count, -1); |
752 | drop_nlink(inode); | 735 | drop_nlink(inode); |
753 | mlog_errno(err); | 736 | mlog_errno(err); |
754 | goto bail; | 737 | goto out_commit; |
755 | } | 738 | } |
756 | 739 | ||
757 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | 740 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); |
758 | if (err) { | 741 | if (err) { |
759 | mlog_errno(err); | 742 | mlog_errno(err); |
760 | goto bail; | 743 | goto out_commit; |
761 | } | 744 | } |
762 | 745 | ||
763 | atomic_inc(&inode->i_count); | 746 | atomic_inc(&inode->i_count); |
764 | dentry->d_op = &ocfs2_dentry_ops; | 747 | dentry->d_op = &ocfs2_dentry_ops; |
765 | d_instantiate(dentry, inode); | 748 | d_instantiate(dentry, inode); |
766 | bail: | 749 | |
767 | if (handle) | 750 | out_commit: |
768 | ocfs2_commit_trans(handle); | 751 | ocfs2_commit_trans(osb, handle); |
752 | out_unlock_inode: | ||
753 | ocfs2_meta_unlock(inode, 1); | ||
754 | |||
755 | out: | ||
756 | ocfs2_meta_unlock(dir, 1); | ||
757 | |||
769 | if (de_bh) | 758 | if (de_bh) |
770 | brelse(de_bh); | 759 | brelse(de_bh); |
771 | if (fe_bh) | 760 | if (fe_bh) |
@@ -812,13 +801,15 @@ static int ocfs2_unlink(struct inode *dir, | |||
812 | struct dentry *dentry) | 801 | struct dentry *dentry) |
813 | { | 802 | { |
814 | int status; | 803 | int status; |
804 | int child_locked = 0; | ||
815 | struct inode *inode = dentry->d_inode; | 805 | struct inode *inode = dentry->d_inode; |
806 | struct inode *orphan_dir = NULL; | ||
816 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 807 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
817 | u64 blkno; | 808 | u64 blkno; |
818 | struct ocfs2_dinode *fe = NULL; | 809 | struct ocfs2_dinode *fe = NULL; |
819 | struct buffer_head *fe_bh = NULL; | 810 | struct buffer_head *fe_bh = NULL; |
820 | struct buffer_head *parent_node_bh = NULL; | 811 | struct buffer_head *parent_node_bh = NULL; |
821 | struct ocfs2_journal_handle *handle = NULL; | 812 | handle_t *handle = NULL; |
822 | struct ocfs2_dir_entry *dirent = NULL; | 813 | struct ocfs2_dir_entry *dirent = NULL; |
823 | struct buffer_head *dirent_bh = NULL; | 814 | struct buffer_head *dirent_bh = NULL; |
824 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 815 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
@@ -833,22 +824,14 @@ static int ocfs2_unlink(struct inode *dir, | |||
833 | 824 | ||
834 | if (inode == osb->root_inode) { | 825 | if (inode == osb->root_inode) { |
835 | mlog(0, "Cannot delete the root directory\n"); | 826 | mlog(0, "Cannot delete the root directory\n"); |
836 | status = -EPERM; | 827 | return -EPERM; |
837 | goto leave; | ||
838 | } | ||
839 | |||
840 | handle = ocfs2_alloc_handle(osb); | ||
841 | if (handle == NULL) { | ||
842 | status = -ENOMEM; | ||
843 | mlog_errno(status); | ||
844 | goto leave; | ||
845 | } | 828 | } |
846 | 829 | ||
847 | status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1); | 830 | status = ocfs2_meta_lock(dir, &parent_node_bh, 1); |
848 | if (status < 0) { | 831 | if (status < 0) { |
849 | if (status != -ENOENT) | 832 | if (status != -ENOENT) |
850 | mlog_errno(status); | 833 | mlog_errno(status); |
851 | goto leave; | 834 | return status; |
852 | } | 835 | } |
853 | 836 | ||
854 | status = ocfs2_find_files_on_disk(dentry->d_name.name, | 837 | status = ocfs2_find_files_on_disk(dentry->d_name.name, |
@@ -869,12 +852,13 @@ static int ocfs2_unlink(struct inode *dir, | |||
869 | goto leave; | 852 | goto leave; |
870 | } | 853 | } |
871 | 854 | ||
872 | status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 855 | status = ocfs2_meta_lock(inode, &fe_bh, 1); |
873 | if (status < 0) { | 856 | if (status < 0) { |
874 | if (status != -ENOENT) | 857 | if (status != -ENOENT) |
875 | mlog_errno(status); | 858 | mlog_errno(status); |
876 | goto leave; | 859 | goto leave; |
877 | } | 860 | } |
861 | child_locked = 1; | ||
878 | 862 | ||
879 | if (S_ISDIR(inode->i_mode)) { | 863 | if (S_ISDIR(inode->i_mode)) { |
880 | if (!ocfs2_empty_dir(inode)) { | 864 | if (!ocfs2_empty_dir(inode)) { |
@@ -895,7 +879,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
895 | } | 879 | } |
896 | 880 | ||
897 | if (inode_is_unlinkable(inode)) { | 881 | if (inode_is_unlinkable(inode)) { |
898 | status = ocfs2_prepare_orphan_dir(osb, handle, inode, | 882 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode, |
899 | orphan_name, | 883 | orphan_name, |
900 | &orphan_entry_bh); | 884 | &orphan_entry_bh); |
901 | if (status < 0) { | 885 | if (status < 0) { |
@@ -904,7 +888,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
904 | } | 888 | } |
905 | } | 889 | } |
906 | 890 | ||
907 | handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); | 891 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); |
908 | if (IS_ERR(handle)) { | 892 | if (IS_ERR(handle)) { |
909 | status = PTR_ERR(handle); | 893 | status = PTR_ERR(handle); |
910 | handle = NULL; | 894 | handle = NULL; |
@@ -923,7 +907,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
923 | 907 | ||
924 | if (inode_is_unlinkable(inode)) { | 908 | if (inode_is_unlinkable(inode)) { |
925 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, | 909 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, |
926 | orphan_entry_bh); | 910 | orphan_entry_bh, orphan_dir); |
927 | if (status < 0) { | 911 | if (status < 0) { |
928 | mlog_errno(status); | 912 | mlog_errno(status); |
929 | goto leave; | 913 | goto leave; |
@@ -960,7 +944,19 @@ static int ocfs2_unlink(struct inode *dir, | |||
960 | 944 | ||
961 | leave: | 945 | leave: |
962 | if (handle) | 946 | if (handle) |
963 | ocfs2_commit_trans(handle); | 947 | ocfs2_commit_trans(osb, handle); |
948 | |||
949 | if (child_locked) | ||
950 | ocfs2_meta_unlock(inode, 1); | ||
951 | |||
952 | ocfs2_meta_unlock(dir, 1); | ||
953 | |||
954 | if (orphan_dir) { | ||
955 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
956 | ocfs2_meta_unlock(orphan_dir, 1); | ||
957 | mutex_unlock(&orphan_dir->i_mutex); | ||
958 | iput(orphan_dir); | ||
959 | } | ||
964 | 960 | ||
965 | if (fe_bh) | 961 | if (fe_bh) |
966 | brelse(fe_bh); | 962 | brelse(fe_bh); |
@@ -984,7 +980,6 @@ leave: | |||
984 | * if they have the same id, then the 1st one is the only one locked. | 980 | * if they have the same id, then the 1st one is the only one locked. |
985 | */ | 981 | */ |
986 | static int ocfs2_double_lock(struct ocfs2_super *osb, | 982 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
987 | struct ocfs2_journal_handle *handle, | ||
988 | struct buffer_head **bh1, | 983 | struct buffer_head **bh1, |
989 | struct inode *inode1, | 984 | struct inode *inode1, |
990 | struct buffer_head **bh2, | 985 | struct buffer_head **bh2, |
@@ -1000,8 +995,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1000 | (unsigned long long)oi1->ip_blkno, | 995 | (unsigned long long)oi1->ip_blkno, |
1001 | (unsigned long long)oi2->ip_blkno); | 996 | (unsigned long long)oi2->ip_blkno); |
1002 | 997 | ||
1003 | BUG_ON(!handle); | ||
1004 | |||
1005 | if (*bh1) | 998 | if (*bh1) |
1006 | *bh1 = NULL; | 999 | *bh1 = NULL; |
1007 | if (*bh2) | 1000 | if (*bh2) |
@@ -1021,25 +1014,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1021 | inode1 = tmpinode; | 1014 | inode1 = tmpinode; |
1022 | } | 1015 | } |
1023 | /* lock id2 */ | 1016 | /* lock id2 */ |
1024 | status = ocfs2_meta_lock(inode2, handle, bh2, 1); | 1017 | status = ocfs2_meta_lock(inode2, bh2, 1); |
1025 | if (status < 0) { | 1018 | if (status < 0) { |
1026 | if (status != -ENOENT) | 1019 | if (status != -ENOENT) |
1027 | mlog_errno(status); | 1020 | mlog_errno(status); |
1028 | goto bail; | 1021 | goto bail; |
1029 | } | 1022 | } |
1030 | } | 1023 | } |
1024 | |||
1031 | /* lock id1 */ | 1025 | /* lock id1 */ |
1032 | status = ocfs2_meta_lock(inode1, handle, bh1, 1); | 1026 | status = ocfs2_meta_lock(inode1, bh1, 1); |
1033 | if (status < 0) { | 1027 | if (status < 0) { |
1028 | /* | ||
1029 | * An error return must mean that no cluster locks | ||
1030 | * were held on function exit. | ||
1031 | */ | ||
1032 | if (oi1->ip_blkno != oi2->ip_blkno) | ||
1033 | ocfs2_meta_unlock(inode2, 1); | ||
1034 | |||
1034 | if (status != -ENOENT) | 1035 | if (status != -ENOENT) |
1035 | mlog_errno(status); | 1036 | mlog_errno(status); |
1036 | goto bail; | ||
1037 | } | 1037 | } |
1038 | |||
1038 | bail: | 1039 | bail: |
1039 | mlog_exit(status); | 1040 | mlog_exit(status); |
1040 | return status; | 1041 | return status; |
1041 | } | 1042 | } |
1042 | 1043 | ||
1044 | static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) | ||
1045 | { | ||
1046 | ocfs2_meta_unlock(inode1, 1); | ||
1047 | |||
1048 | if (inode1 != inode2) | ||
1049 | ocfs2_meta_unlock(inode2, 1); | ||
1050 | } | ||
1051 | |||
1043 | #define PARENT_INO(buffer) \ | 1052 | #define PARENT_INO(buffer) \ |
1044 | ((struct ocfs2_dir_entry *) \ | 1053 | ((struct ocfs2_dir_entry *) \ |
1045 | ((char *)buffer + \ | 1054 | ((char *)buffer + \ |
@@ -1050,9 +1059,11 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1050 | struct inode *new_dir, | 1059 | struct inode *new_dir, |
1051 | struct dentry *new_dentry) | 1060 | struct dentry *new_dentry) |
1052 | { | 1061 | { |
1053 | int status = 0, rename_lock = 0; | 1062 | int status = 0, rename_lock = 0, parents_locked = 0; |
1063 | int old_child_locked = 0, new_child_locked = 0; | ||
1054 | struct inode *old_inode = old_dentry->d_inode; | 1064 | struct inode *old_inode = old_dentry->d_inode; |
1055 | struct inode *new_inode = new_dentry->d_inode; | 1065 | struct inode *new_inode = new_dentry->d_inode; |
1066 | struct inode *orphan_dir = NULL; | ||
1056 | struct ocfs2_dinode *newfe = NULL; | 1067 | struct ocfs2_dinode *newfe = NULL; |
1057 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 1068 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
1058 | struct buffer_head *orphan_entry_bh = NULL; | 1069 | struct buffer_head *orphan_entry_bh = NULL; |
@@ -1060,7 +1071,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1060 | struct buffer_head *insert_entry_bh = NULL; | 1071 | struct buffer_head *insert_entry_bh = NULL; |
1061 | struct ocfs2_super *osb = NULL; | 1072 | struct ocfs2_super *osb = NULL; |
1062 | u64 newfe_blkno; | 1073 | u64 newfe_blkno; |
1063 | struct ocfs2_journal_handle *handle = NULL; | 1074 | handle_t *handle = NULL; |
1064 | struct buffer_head *old_dir_bh = NULL; | 1075 | struct buffer_head *old_dir_bh = NULL; |
1065 | struct buffer_head *new_dir_bh = NULL; | 1076 | struct buffer_head *new_dir_bh = NULL; |
1066 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry | 1077 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry |
@@ -1105,21 +1116,14 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1105 | rename_lock = 1; | 1116 | rename_lock = 1; |
1106 | } | 1117 | } |
1107 | 1118 | ||
1108 | handle = ocfs2_alloc_handle(osb); | ||
1109 | if (handle == NULL) { | ||
1110 | status = -ENOMEM; | ||
1111 | mlog_errno(status); | ||
1112 | goto bail; | ||
1113 | } | ||
1114 | |||
1115 | /* if old and new are the same, this'll just do one lock. */ | 1119 | /* if old and new are the same, this'll just do one lock. */ |
1116 | status = ocfs2_double_lock(osb, handle, | 1120 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
1117 | &old_dir_bh, old_dir, | 1121 | &new_dir_bh, new_dir); |
1118 | &new_dir_bh, new_dir); | ||
1119 | if (status < 0) { | 1122 | if (status < 0) { |
1120 | mlog_errno(status); | 1123 | mlog_errno(status); |
1121 | goto bail; | 1124 | goto bail; |
1122 | } | 1125 | } |
1126 | parents_locked = 1; | ||
1123 | 1127 | ||
1124 | /* make sure both dirs have bhs | 1128 | /* make sure both dirs have bhs |
1125 | * get an extra ref on old_dir_bh if old==new */ | 1129 | * get an extra ref on old_dir_bh if old==new */ |
@@ -1140,12 +1144,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1140 | * the vote thread on other nodes won't have to concurrently | 1144 | * the vote thread on other nodes won't have to concurrently |
1141 | * downconvert the inode and the dentry locks. | 1145 | * downconvert the inode and the dentry locks. |
1142 | */ | 1146 | */ |
1143 | status = ocfs2_meta_lock(old_inode, handle, NULL, 1); | 1147 | status = ocfs2_meta_lock(old_inode, NULL, 1); |
1144 | if (status < 0) { | 1148 | if (status < 0) { |
1145 | if (status != -ENOENT) | 1149 | if (status != -ENOENT) |
1146 | mlog_errno(status); | 1150 | mlog_errno(status); |
1147 | goto bail; | 1151 | goto bail; |
1148 | } | 1152 | } |
1153 | old_child_locked = 1; | ||
1149 | 1154 | ||
1150 | status = ocfs2_remote_dentry_delete(old_dentry); | 1155 | status = ocfs2_remote_dentry_delete(old_dentry); |
1151 | if (status < 0) { | 1156 | if (status < 0) { |
@@ -1231,12 +1236,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1231 | goto bail; | 1236 | goto bail; |
1232 | } | 1237 | } |
1233 | 1238 | ||
1234 | status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); | 1239 | status = ocfs2_meta_lock(new_inode, &newfe_bh, 1); |
1235 | if (status < 0) { | 1240 | if (status < 0) { |
1236 | if (status != -ENOENT) | 1241 | if (status != -ENOENT) |
1237 | mlog_errno(status); | 1242 | mlog_errno(status); |
1238 | goto bail; | 1243 | goto bail; |
1239 | } | 1244 | } |
1245 | new_child_locked = 1; | ||
1240 | 1246 | ||
1241 | status = ocfs2_remote_dentry_delete(new_dentry); | 1247 | status = ocfs2_remote_dentry_delete(new_dentry); |
1242 | if (status < 0) { | 1248 | if (status < 0) { |
@@ -1252,7 +1258,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1252 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); | 1258 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); |
1253 | 1259 | ||
1254 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { | 1260 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { |
1255 | status = ocfs2_prepare_orphan_dir(osb, handle, | 1261 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, |
1256 | new_inode, | 1262 | new_inode, |
1257 | orphan_name, | 1263 | orphan_name, |
1258 | &orphan_entry_bh); | 1264 | &orphan_entry_bh); |
@@ -1280,7 +1286,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1280 | } | 1286 | } |
1281 | } | 1287 | } |
1282 | 1288 | ||
1283 | handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS); | 1289 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); |
1284 | if (IS_ERR(handle)) { | 1290 | if (IS_ERR(handle)) { |
1285 | status = PTR_ERR(handle); | 1291 | status = PTR_ERR(handle); |
1286 | handle = NULL; | 1292 | handle = NULL; |
@@ -1307,7 +1313,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1307 | (newfe->i_links_count == cpu_to_le16(1))){ | 1313 | (newfe->i_links_count == cpu_to_le16(1))){ |
1308 | status = ocfs2_orphan_add(osb, handle, new_inode, | 1314 | status = ocfs2_orphan_add(osb, handle, new_inode, |
1309 | newfe, orphan_name, | 1315 | newfe, orphan_name, |
1310 | orphan_entry_bh); | 1316 | orphan_entry_bh, orphan_dir); |
1311 | if (status < 0) { | 1317 | if (status < 0) { |
1312 | mlog_errno(status); | 1318 | mlog_errno(status); |
1313 | goto bail; | 1319 | goto bail; |
@@ -1424,7 +1430,23 @@ bail: | |||
1424 | ocfs2_rename_unlock(osb); | 1430 | ocfs2_rename_unlock(osb); |
1425 | 1431 | ||
1426 | if (handle) | 1432 | if (handle) |
1427 | ocfs2_commit_trans(handle); | 1433 | ocfs2_commit_trans(osb, handle); |
1434 | |||
1435 | if (parents_locked) | ||
1436 | ocfs2_double_unlock(old_dir, new_dir); | ||
1437 | |||
1438 | if (old_child_locked) | ||
1439 | ocfs2_meta_unlock(old_inode, 1); | ||
1440 | |||
1441 | if (new_child_locked) | ||
1442 | ocfs2_meta_unlock(new_inode, 1); | ||
1443 | |||
1444 | if (orphan_dir) { | ||
1445 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
1446 | ocfs2_meta_unlock(orphan_dir, 1); | ||
1447 | mutex_unlock(&orphan_dir->i_mutex); | ||
1448 | iput(orphan_dir); | ||
1449 | } | ||
1428 | 1450 | ||
1429 | if (new_inode) | 1451 | if (new_inode) |
1430 | sync_mapping_buffers(old_inode->i_mapping); | 1452 | sync_mapping_buffers(old_inode->i_mapping); |
@@ -1458,7 +1480,7 @@ bail: | |||
1458 | * data, including the null terminator. | 1480 | * data, including the null terminator. |
1459 | */ | 1481 | */ |
1460 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 1482 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
1461 | struct ocfs2_journal_handle *handle, | 1483 | handle_t *handle, |
1462 | struct inode *inode, | 1484 | struct inode *inode, |
1463 | const char *symname) | 1485 | const char *symname) |
1464 | { | 1486 | { |
@@ -1573,7 +1595,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1573 | struct buffer_head *parent_fe_bh = NULL; | 1595 | struct buffer_head *parent_fe_bh = NULL; |
1574 | struct ocfs2_dinode *fe = NULL; | 1596 | struct ocfs2_dinode *fe = NULL; |
1575 | struct ocfs2_dinode *dirfe; | 1597 | struct ocfs2_dinode *dirfe; |
1576 | struct ocfs2_journal_handle *handle = NULL; | 1598 | handle_t *handle = NULL; |
1577 | struct ocfs2_alloc_context *inode_ac = NULL; | 1599 | struct ocfs2_alloc_context *inode_ac = NULL; |
1578 | struct ocfs2_alloc_context *data_ac = NULL; | 1600 | struct ocfs2_alloc_context *data_ac = NULL; |
1579 | 1601 | ||
@@ -1587,19 +1609,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1587 | 1609 | ||
1588 | credits = ocfs2_calc_symlink_credits(sb); | 1610 | credits = ocfs2_calc_symlink_credits(sb); |
1589 | 1611 | ||
1590 | handle = ocfs2_alloc_handle(osb); | ||
1591 | if (handle == NULL) { | ||
1592 | status = -ENOMEM; | ||
1593 | mlog_errno(status); | ||
1594 | goto bail; | ||
1595 | } | ||
1596 | |||
1597 | /* lock the parent directory */ | 1612 | /* lock the parent directory */ |
1598 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 1613 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
1599 | if (status < 0) { | 1614 | if (status < 0) { |
1600 | if (status != -ENOENT) | 1615 | if (status != -ENOENT) |
1601 | mlog_errno(status); | 1616 | mlog_errno(status); |
1602 | goto bail; | 1617 | return status; |
1603 | } | 1618 | } |
1604 | 1619 | ||
1605 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 1620 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
@@ -1622,7 +1637,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1622 | goto bail; | 1637 | goto bail; |
1623 | } | 1638 | } |
1624 | 1639 | ||
1625 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 1640 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
1626 | if (status < 0) { | 1641 | if (status < 0) { |
1627 | if (status != -ENOSPC) | 1642 | if (status != -ENOSPC) |
1628 | mlog_errno(status); | 1643 | mlog_errno(status); |
@@ -1631,7 +1646,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1631 | 1646 | ||
1632 | /* don't reserve bitmap space for fast symlinks. */ | 1647 | /* don't reserve bitmap space for fast symlinks. */ |
1633 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1648 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1634 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 1649 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
1635 | if (status < 0) { | 1650 | if (status < 0) { |
1636 | if (status != -ENOSPC) | 1651 | if (status != -ENOSPC) |
1637 | mlog_errno(status); | 1652 | mlog_errno(status); |
@@ -1639,7 +1654,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1639 | } | 1654 | } |
1640 | } | 1655 | } |
1641 | 1656 | ||
1642 | handle = ocfs2_start_trans(osb, handle, credits); | 1657 | handle = ocfs2_start_trans(osb, credits); |
1643 | if (IS_ERR(handle)) { | 1658 | if (IS_ERR(handle)) { |
1644 | status = PTR_ERR(handle); | 1659 | status = PTR_ERR(handle); |
1645 | handle = NULL; | 1660 | handle = NULL; |
@@ -1717,7 +1732,10 @@ static int ocfs2_symlink(struct inode *dir, | |||
1717 | d_instantiate(dentry, inode); | 1732 | d_instantiate(dentry, inode); |
1718 | bail: | 1733 | bail: |
1719 | if (handle) | 1734 | if (handle) |
1720 | ocfs2_commit_trans(handle); | 1735 | ocfs2_commit_trans(osb, handle); |
1736 | |||
1737 | ocfs2_meta_unlock(dir, 1); | ||
1738 | |||
1721 | if (new_fe_bh) | 1739 | if (new_fe_bh) |
1722 | brelse(new_fe_bh); | 1740 | brelse(new_fe_bh); |
1723 | if (parent_fe_bh) | 1741 | if (parent_fe_bh) |
@@ -1768,7 +1786,7 @@ int ocfs2_check_dir_entry(struct inode * dir, | |||
1768 | * If you pass me insert_bh, I'll skip the search of the other dir | 1786 | * If you pass me insert_bh, I'll skip the search of the other dir |
1769 | * blocks and put the record in there. | 1787 | * blocks and put the record in there. |
1770 | */ | 1788 | */ |
1771 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 1789 | static int __ocfs2_add_entry(handle_t *handle, |
1772 | struct inode *dir, | 1790 | struct inode *dir, |
1773 | const char *name, int namelen, | 1791 | const char *name, int namelen, |
1774 | struct inode *inode, u64 blkno, | 1792 | struct inode *inode, u64 blkno, |
@@ -1854,7 +1872,7 @@ bail: | |||
1854 | * ocfs2_delete_entry deletes a directory entry by merging it with the | 1872 | * ocfs2_delete_entry deletes a directory entry by merging it with the |
1855 | * previous entry | 1873 | * previous entry |
1856 | */ | 1874 | */ |
1857 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 1875 | static int ocfs2_delete_entry(handle_t *handle, |
1858 | struct inode *dir, | 1876 | struct inode *dir, |
1859 | struct ocfs2_dir_entry *de_del, | 1877 | struct ocfs2_dir_entry *de_del, |
1860 | struct buffer_head *bh) | 1878 | struct buffer_head *bh) |
@@ -2085,19 +2103,19 @@ bail: | |||
2085 | } | 2103 | } |
2086 | 2104 | ||
2087 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 2105 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
2088 | struct ocfs2_journal_handle *handle, | 2106 | struct inode **ret_orphan_dir, |
2089 | struct inode *inode, | 2107 | struct inode *inode, |
2090 | char *name, | 2108 | char *name, |
2091 | struct buffer_head **de_bh) | 2109 | struct buffer_head **de_bh) |
2092 | { | 2110 | { |
2093 | struct inode *orphan_dir_inode = NULL; | 2111 | struct inode *orphan_dir_inode; |
2094 | struct buffer_head *orphan_dir_bh = NULL; | 2112 | struct buffer_head *orphan_dir_bh = NULL; |
2095 | int status = 0; | 2113 | int status = 0; |
2096 | 2114 | ||
2097 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); | 2115 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); |
2098 | if (status < 0) { | 2116 | if (status < 0) { |
2099 | mlog_errno(status); | 2117 | mlog_errno(status); |
2100 | goto leave; | 2118 | return status; |
2101 | } | 2119 | } |
2102 | 2120 | ||
2103 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 2121 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
@@ -2106,11 +2124,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2106 | if (!orphan_dir_inode) { | 2124 | if (!orphan_dir_inode) { |
2107 | status = -ENOENT; | 2125 | status = -ENOENT; |
2108 | mlog_errno(status); | 2126 | mlog_errno(status); |
2109 | goto leave; | 2127 | return status; |
2110 | } | 2128 | } |
2111 | 2129 | ||
2112 | ocfs2_handle_add_inode(handle, orphan_dir_inode); | 2130 | mutex_lock(&orphan_dir_inode->i_mutex); |
2113 | status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1); | 2131 | |
2132 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); | ||
2114 | if (status < 0) { | 2133 | if (status < 0) { |
2115 | mlog_errno(status); | 2134 | mlog_errno(status); |
2116 | goto leave; | 2135 | goto leave; |
@@ -2120,13 +2139,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2120 | orphan_dir_bh, name, | 2139 | orphan_dir_bh, name, |
2121 | OCFS2_ORPHAN_NAMELEN, de_bh); | 2140 | OCFS2_ORPHAN_NAMELEN, de_bh); |
2122 | if (status < 0) { | 2141 | if (status < 0) { |
2142 | ocfs2_meta_unlock(orphan_dir_inode, 1); | ||
2143 | |||
2123 | mlog_errno(status); | 2144 | mlog_errno(status); |
2124 | goto leave; | 2145 | goto leave; |
2125 | } | 2146 | } |
2126 | 2147 | ||
2148 | *ret_orphan_dir = orphan_dir_inode; | ||
2149 | |||
2127 | leave: | 2150 | leave: |
2128 | if (orphan_dir_inode) | 2151 | if (status) { |
2152 | mutex_unlock(&orphan_dir_inode->i_mutex); | ||
2129 | iput(orphan_dir_inode); | 2153 | iput(orphan_dir_inode); |
2154 | } | ||
2130 | 2155 | ||
2131 | if (orphan_dir_bh) | 2156 | if (orphan_dir_bh) |
2132 | brelse(orphan_dir_bh); | 2157 | brelse(orphan_dir_bh); |
@@ -2136,28 +2161,19 @@ leave: | |||
2136 | } | 2161 | } |
2137 | 2162 | ||
2138 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 2163 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
2139 | struct ocfs2_journal_handle *handle, | 2164 | handle_t *handle, |
2140 | struct inode *inode, | 2165 | struct inode *inode, |
2141 | struct ocfs2_dinode *fe, | 2166 | struct ocfs2_dinode *fe, |
2142 | char *name, | 2167 | char *name, |
2143 | struct buffer_head *de_bh) | 2168 | struct buffer_head *de_bh, |
2169 | struct inode *orphan_dir_inode) | ||
2144 | { | 2170 | { |
2145 | struct inode *orphan_dir_inode = NULL; | ||
2146 | struct buffer_head *orphan_dir_bh = NULL; | 2171 | struct buffer_head *orphan_dir_bh = NULL; |
2147 | int status = 0; | 2172 | int status = 0; |
2148 | struct ocfs2_dinode *orphan_fe; | 2173 | struct ocfs2_dinode *orphan_fe; |
2149 | 2174 | ||
2150 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 2175 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
2151 | 2176 | ||
2152 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | ||
2153 | ORPHAN_DIR_SYSTEM_INODE, | ||
2154 | osb->slot_num); | ||
2155 | if (!orphan_dir_inode) { | ||
2156 | status = -ENOENT; | ||
2157 | mlog_errno(status); | ||
2158 | goto leave; | ||
2159 | } | ||
2160 | |||
2161 | status = ocfs2_read_block(osb, | 2177 | status = ocfs2_read_block(osb, |
2162 | OCFS2_I(orphan_dir_inode)->ip_blkno, | 2178 | OCFS2_I(orphan_dir_inode)->ip_blkno, |
2163 | &orphan_dir_bh, OCFS2_BH_CACHED, | 2179 | &orphan_dir_bh, OCFS2_BH_CACHED, |
@@ -2209,9 +2225,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
2209 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); | 2225 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); |
2210 | 2226 | ||
2211 | leave: | 2227 | leave: |
2212 | if (orphan_dir_inode) | ||
2213 | iput(orphan_dir_inode); | ||
2214 | |||
2215 | if (orphan_dir_bh) | 2228 | if (orphan_dir_bh) |
2216 | brelse(orphan_dir_bh); | 2229 | brelse(orphan_dir_bh); |
2217 | 2230 | ||
@@ -2221,7 +2234,7 @@ leave: | |||
2221 | 2234 | ||
2222 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ | 2235 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ |
2223 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 2236 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
2224 | struct ocfs2_journal_handle *handle, | 2237 | handle_t *handle, |
2225 | struct inode *orphan_dir_inode, | 2238 | struct inode *orphan_dir_inode, |
2226 | struct inode *inode, | 2239 | struct inode *inode, |
2227 | struct buffer_head *orphan_dir_bh) | 2240 | struct buffer_head *orphan_dir_bh) |
@@ -2300,4 +2313,5 @@ struct inode_operations ocfs2_dir_iops = { | |||
2300 | .rename = ocfs2_rename, | 2313 | .rename = ocfs2_rename, |
2301 | .setattr = ocfs2_setattr, | 2314 | .setattr = ocfs2_setattr, |
2302 | .getattr = ocfs2_getattr, | 2315 | .getattr = ocfs2_getattr, |
2316 | .permission = ocfs2_permission, | ||
2303 | }; | 2317 | }; |
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h index deaaa97dbf0b..8425944fcccd 100644 --- a/fs/ocfs2/namei.h +++ b/fs/ocfs2/namei.h | |||
@@ -39,7 +39,7 @@ struct buffer_head *ocfs2_find_entry(const char *name, | |||
39 | struct inode *dir, | 39 | struct inode *dir, |
40 | struct ocfs2_dir_entry **res_dir); | 40 | struct ocfs2_dir_entry **res_dir); |
41 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 41 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
42 | struct ocfs2_journal_handle *handle, | 42 | handle_t *handle, |
43 | struct inode *orphan_dir_inode, | 43 | struct inode *orphan_dir_inode, |
44 | struct inode *inode, | 44 | struct inode *inode, |
45 | struct buffer_head *orphan_dir_bh); | 45 | struct buffer_head *orphan_dir_bh); |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 0462a7f4e21b..db8e77cd35d3 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/jbd.h> | ||
37 | 38 | ||
38 | #include "cluster/nodemanager.h" | 39 | #include "cluster/nodemanager.h" |
39 | #include "cluster/heartbeat.h" | 40 | #include "cluster/heartbeat.h" |
@@ -179,9 +180,9 @@ enum ocfs2_mount_options | |||
179 | #define OCFS2_OSB_SOFT_RO 0x0001 | 180 | #define OCFS2_OSB_SOFT_RO 0x0001 |
180 | #define OCFS2_OSB_HARD_RO 0x0002 | 181 | #define OCFS2_OSB_HARD_RO 0x0002 |
181 | #define OCFS2_OSB_ERROR_FS 0x0004 | 182 | #define OCFS2_OSB_ERROR_FS 0x0004 |
183 | #define OCFS2_DEFAULT_ATIME_QUANTUM 60 | ||
182 | 184 | ||
183 | struct ocfs2_journal; | 185 | struct ocfs2_journal; |
184 | struct ocfs2_journal_handle; | ||
185 | struct ocfs2_super | 186 | struct ocfs2_super |
186 | { | 187 | { |
187 | struct task_struct *commit_task; | 188 | struct task_struct *commit_task; |
@@ -218,6 +219,7 @@ struct ocfs2_super | |||
218 | unsigned long osb_flags; | 219 | unsigned long osb_flags; |
219 | 220 | ||
220 | unsigned long s_mount_opt; | 221 | unsigned long s_mount_opt; |
222 | unsigned int s_atime_quantum; | ||
221 | 223 | ||
222 | u16 max_slots; | 224 | u16 max_slots; |
223 | s16 node_num; | 225 | s16 node_num; |
@@ -283,7 +285,7 @@ struct ocfs2_super | |||
283 | /* Truncate log info */ | 285 | /* Truncate log info */ |
284 | struct inode *osb_tl_inode; | 286 | struct inode *osb_tl_inode; |
285 | struct buffer_head *osb_tl_bh; | 287 | struct buffer_head *osb_tl_bh; |
286 | struct work_struct osb_truncate_log_wq; | 288 | struct delayed_work osb_truncate_log_wq; |
287 | 289 | ||
288 | struct ocfs2_node_map osb_recovering_orphan_dirs; | 290 | struct ocfs2_node_map osb_recovering_orphan_dirs; |
289 | unsigned int *osb_orphan_wipes; | 291 | unsigned int *osb_orphan_wipes; |
@@ -347,6 +349,11 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb) | |||
347 | return ret; | 349 | return ret; |
348 | } | 350 | } |
349 | 351 | ||
352 | static inline int ocfs2_mount_local(struct ocfs2_super *osb) | ||
353 | { | ||
354 | return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT); | ||
355 | } | ||
356 | |||
350 | #define OCFS2_IS_VALID_DINODE(ptr) \ | 357 | #define OCFS2_IS_VALID_DINODE(ptr) \ |
351 | (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE)) | 358 | (!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE)) |
352 | 359 | ||
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 3330a5dc6be2..b5c68567077e 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -86,7 +86,7 @@ | |||
86 | OCFS2_SB(sb)->s_feature_incompat &= ~(mask) | 86 | OCFS2_SB(sb)->s_feature_incompat &= ~(mask) |
87 | 87 | ||
88 | #define OCFS2_FEATURE_COMPAT_SUPP 0 | 88 | #define OCFS2_FEATURE_COMPAT_SUPP 0 |
89 | #define OCFS2_FEATURE_INCOMPAT_SUPP 0 | 89 | #define OCFS2_FEATURE_INCOMPAT_SUPP OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT |
90 | #define OCFS2_FEATURE_RO_COMPAT_SUPP 0 | 90 | #define OCFS2_FEATURE_RO_COMPAT_SUPP 0 |
91 | 91 | ||
92 | /* | 92 | /* |
@@ -96,6 +96,18 @@ | |||
96 | */ | 96 | */ |
97 | #define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV 0x0002 | 97 | #define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV 0x0002 |
98 | 98 | ||
99 | /* | ||
100 | * tunefs sets this incompat flag before starting the resize and clears it | ||
101 | * at the end. This flag protects users from inadvertently mounting the fs | ||
102 | * after an aborted run without fsck-ing. | ||
103 | */ | ||
104 | #define OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG 0x0004 | ||
105 | |||
106 | /* Used to denote a non-clustered volume */ | ||
107 | #define OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT 0x0008 | ||
108 | |||
109 | /* Support for sparse allocation in b-trees */ | ||
110 | #define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010 | ||
99 | 111 | ||
100 | /* | 112 | /* |
101 | * Flags on ocfs2_dinode.i_flags | 113 | * Flags on ocfs2_dinode.i_flags |
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index aa6f5aadedc4..2d3ac32cb74e 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c | |||
@@ -175,7 +175,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb) | |||
175 | struct buffer_head *bh = NULL; | 175 | struct buffer_head *bh = NULL; |
176 | struct ocfs2_slot_info *si; | 176 | struct ocfs2_slot_info *si; |
177 | 177 | ||
178 | si = kcalloc(1, sizeof(struct ocfs2_slot_info), GFP_KERNEL); | 178 | si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL); |
179 | if (!si) { | 179 | if (!si) { |
180 | status = -ENOMEM; | 180 | status = -ENOMEM; |
181 | mlog_errno(status); | 181 | mlog_errno(status); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 9d91e66f51a9..6dbb11762759 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -49,7 +49,7 @@ | |||
49 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); | 49 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); |
50 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); | 50 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); |
51 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); | 51 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); |
52 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, | 52 | static int ocfs2_block_group_fill(handle_t *handle, |
53 | struct inode *alloc_inode, | 53 | struct inode *alloc_inode, |
54 | struct buffer_head *bg_bh, | 54 | struct buffer_head *bg_bh, |
55 | u64 group_blkno, | 55 | u64 group_blkno, |
@@ -59,9 +59,6 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
59 | struct inode *alloc_inode, | 59 | struct inode *alloc_inode, |
60 | struct buffer_head *bh); | 60 | struct buffer_head *bh); |
61 | 61 | ||
62 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | ||
63 | struct ocfs2_alloc_context *ac); | ||
64 | |||
65 | static int ocfs2_cluster_group_search(struct inode *inode, | 62 | static int ocfs2_cluster_group_search(struct inode *inode, |
66 | struct buffer_head *group_bh, | 63 | struct buffer_head *group_bh, |
67 | u32 bits_wanted, u32 min_bits, | 64 | u32 bits_wanted, u32 min_bits, |
@@ -72,6 +69,7 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
72 | u16 *bit_off, u16 *bits_found); | 69 | u16 *bit_off, u16 *bits_found); |
73 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | 70 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, |
74 | struct ocfs2_alloc_context *ac, | 71 | struct ocfs2_alloc_context *ac, |
72 | handle_t *handle, | ||
75 | u32 bits_wanted, | 73 | u32 bits_wanted, |
76 | u32 min_bits, | 74 | u32 min_bits, |
77 | u16 *bit_off, | 75 | u16 *bit_off, |
@@ -79,20 +77,20 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
79 | u64 *bg_blkno); | 77 | u64 *bg_blkno); |
80 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, | 78 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, |
81 | int nr); | 79 | int nr); |
82 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, | 80 | static inline int ocfs2_block_group_set_bits(handle_t *handle, |
83 | struct inode *alloc_inode, | 81 | struct inode *alloc_inode, |
84 | struct ocfs2_group_desc *bg, | 82 | struct ocfs2_group_desc *bg, |
85 | struct buffer_head *group_bh, | 83 | struct buffer_head *group_bh, |
86 | unsigned int bit_off, | 84 | unsigned int bit_off, |
87 | unsigned int num_bits); | 85 | unsigned int num_bits); |
88 | static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, | 86 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, |
89 | struct inode *alloc_inode, | 87 | struct inode *alloc_inode, |
90 | struct ocfs2_group_desc *bg, | 88 | struct ocfs2_group_desc *bg, |
91 | struct buffer_head *group_bh, | 89 | struct buffer_head *group_bh, |
92 | unsigned int bit_off, | 90 | unsigned int bit_off, |
93 | unsigned int num_bits); | 91 | unsigned int num_bits); |
94 | 92 | ||
95 | static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | 93 | static int ocfs2_relink_block_group(handle_t *handle, |
96 | struct inode *alloc_inode, | 94 | struct inode *alloc_inode, |
97 | struct buffer_head *fe_bh, | 95 | struct buffer_head *fe_bh, |
98 | struct buffer_head *bg_bh, | 96 | struct buffer_head *bg_bh, |
@@ -100,7 +98,7 @@ static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | |||
100 | u16 chain); | 98 | u16 chain); |
101 | static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg, | 99 | static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg, |
102 | u32 wanted); | 100 | u32 wanted); |
103 | static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, | 101 | static int ocfs2_free_suballoc_bits(handle_t *handle, |
104 | struct inode *alloc_inode, | 102 | struct inode *alloc_inode, |
105 | struct buffer_head *alloc_bh, | 103 | struct buffer_head *alloc_bh, |
106 | unsigned int start_bit, | 104 | unsigned int start_bit, |
@@ -120,8 +118,16 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode, | |||
120 | 118 | ||
121 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) | 119 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) |
122 | { | 120 | { |
123 | if (ac->ac_inode) | 121 | struct inode *inode = ac->ac_inode; |
124 | iput(ac->ac_inode); | 122 | |
123 | if (inode) { | ||
124 | if (ac->ac_which != OCFS2_AC_USE_LOCAL) | ||
125 | ocfs2_meta_unlock(inode, 1); | ||
126 | |||
127 | mutex_unlock(&inode->i_mutex); | ||
128 | |||
129 | iput(inode); | ||
130 | } | ||
125 | if (ac->ac_bh) | 131 | if (ac->ac_bh) |
126 | brelse(ac->ac_bh); | 132 | brelse(ac->ac_bh); |
127 | kfree(ac); | 133 | kfree(ac); |
@@ -190,7 +196,7 @@ static int ocfs2_check_group_descriptor(struct super_block *sb, | |||
190 | return 0; | 196 | return 0; |
191 | } | 197 | } |
192 | 198 | ||
193 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, | 199 | static int ocfs2_block_group_fill(handle_t *handle, |
194 | struct inode *alloc_inode, | 200 | struct inode *alloc_inode, |
195 | struct buffer_head *bg_bh, | 201 | struct buffer_head *bg_bh, |
196 | u64 group_blkno, | 202 | u64 group_blkno, |
@@ -273,7 +279,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
273 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; | 279 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; |
274 | struct ocfs2_chain_list *cl; | 280 | struct ocfs2_chain_list *cl; |
275 | struct ocfs2_alloc_context *ac = NULL; | 281 | struct ocfs2_alloc_context *ac = NULL; |
276 | struct ocfs2_journal_handle *handle = NULL; | 282 | handle_t *handle = NULL; |
277 | u32 bit_off, num_bits; | 283 | u32 bit_off, num_bits; |
278 | u16 alloc_rec; | 284 | u16 alloc_rec; |
279 | u64 bg_blkno; | 285 | u64 bg_blkno; |
@@ -284,16 +290,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
284 | 290 | ||
285 | mlog_entry_void(); | 291 | mlog_entry_void(); |
286 | 292 | ||
287 | handle = ocfs2_alloc_handle(osb); | ||
288 | if (!handle) { | ||
289 | status = -ENOMEM; | ||
290 | mlog_errno(status); | ||
291 | goto bail; | ||
292 | } | ||
293 | |||
294 | cl = &fe->id2.i_chain; | 293 | cl = &fe->id2.i_chain; |
295 | status = ocfs2_reserve_clusters(osb, | 294 | status = ocfs2_reserve_clusters(osb, |
296 | handle, | ||
297 | le16_to_cpu(cl->cl_cpg), | 295 | le16_to_cpu(cl->cl_cpg), |
298 | &ac); | 296 | &ac); |
299 | if (status < 0) { | 297 | if (status < 0) { |
@@ -304,7 +302,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
304 | 302 | ||
305 | credits = ocfs2_calc_group_alloc_credits(osb->sb, | 303 | credits = ocfs2_calc_group_alloc_credits(osb->sb, |
306 | le16_to_cpu(cl->cl_cpg)); | 304 | le16_to_cpu(cl->cl_cpg)); |
307 | handle = ocfs2_start_trans(osb, handle, credits); | 305 | handle = ocfs2_start_trans(osb, credits); |
308 | if (IS_ERR(handle)) { | 306 | if (IS_ERR(handle)) { |
309 | status = PTR_ERR(handle); | 307 | status = PTR_ERR(handle); |
310 | handle = NULL; | 308 | handle = NULL; |
@@ -389,7 +387,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
389 | status = 0; | 387 | status = 0; |
390 | bail: | 388 | bail: |
391 | if (handle) | 389 | if (handle) |
392 | ocfs2_commit_trans(handle); | 390 | ocfs2_commit_trans(osb, handle); |
393 | 391 | ||
394 | if (ac) | 392 | if (ac) |
395 | ocfs2_free_alloc_context(ac); | 393 | ocfs2_free_alloc_context(ac); |
@@ -402,27 +400,38 @@ bail: | |||
402 | } | 400 | } |
403 | 401 | ||
404 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | 402 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, |
405 | struct ocfs2_alloc_context *ac) | 403 | struct ocfs2_alloc_context *ac, |
404 | int type, | ||
405 | u32 slot) | ||
406 | { | 406 | { |
407 | int status; | 407 | int status; |
408 | u32 bits_wanted = ac->ac_bits_wanted; | 408 | u32 bits_wanted = ac->ac_bits_wanted; |
409 | struct inode *alloc_inode = ac->ac_inode; | 409 | struct inode *alloc_inode; |
410 | struct buffer_head *bh = NULL; | 410 | struct buffer_head *bh = NULL; |
411 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
412 | struct ocfs2_dinode *fe; | 411 | struct ocfs2_dinode *fe; |
413 | u32 free_bits; | 412 | u32 free_bits; |
414 | 413 | ||
415 | mlog_entry_void(); | 414 | mlog_entry_void(); |
416 | 415 | ||
417 | BUG_ON(handle->flags & OCFS2_HANDLE_STARTED); | 416 | alloc_inode = ocfs2_get_system_file_inode(osb, type, slot); |
417 | if (!alloc_inode) { | ||
418 | mlog_errno(-EINVAL); | ||
419 | return -EINVAL; | ||
420 | } | ||
418 | 421 | ||
419 | ocfs2_handle_add_inode(handle, alloc_inode); | 422 | mutex_lock(&alloc_inode->i_mutex); |
420 | status = ocfs2_meta_lock(alloc_inode, handle, &bh, 1); | 423 | |
424 | status = ocfs2_meta_lock(alloc_inode, &bh, 1); | ||
421 | if (status < 0) { | 425 | if (status < 0) { |
426 | mutex_unlock(&alloc_inode->i_mutex); | ||
427 | iput(alloc_inode); | ||
428 | |||
422 | mlog_errno(status); | 429 | mlog_errno(status); |
423 | goto bail; | 430 | return status; |
424 | } | 431 | } |
425 | 432 | ||
433 | ac->ac_inode = alloc_inode; | ||
434 | |||
426 | fe = (struct ocfs2_dinode *) bh->b_data; | 435 | fe = (struct ocfs2_dinode *) bh->b_data; |
427 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 436 | if (!OCFS2_IS_VALID_DINODE(fe)) { |
428 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 437 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); |
@@ -473,14 +482,13 @@ bail: | |||
473 | } | 482 | } |
474 | 483 | ||
475 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | 484 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, |
476 | struct ocfs2_journal_handle *handle, | ||
477 | struct ocfs2_dinode *fe, | 485 | struct ocfs2_dinode *fe, |
478 | struct ocfs2_alloc_context **ac) | 486 | struct ocfs2_alloc_context **ac) |
479 | { | 487 | { |
480 | int status; | 488 | int status; |
481 | struct inode *alloc_inode = NULL; | 489 | u32 slot; |
482 | 490 | ||
483 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 491 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
484 | if (!(*ac)) { | 492 | if (!(*ac)) { |
485 | status = -ENOMEM; | 493 | status = -ENOMEM; |
486 | mlog_errno(status); | 494 | mlog_errno(status); |
@@ -488,28 +496,18 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | |||
488 | } | 496 | } |
489 | 497 | ||
490 | (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); | 498 | (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); |
491 | (*ac)->ac_handle = handle; | ||
492 | (*ac)->ac_which = OCFS2_AC_USE_META; | 499 | (*ac)->ac_which = OCFS2_AC_USE_META; |
493 | 500 | ||
494 | #ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS | 501 | #ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS |
495 | alloc_inode = ocfs2_get_system_file_inode(osb, | 502 | slot = 0; |
496 | EXTENT_ALLOC_SYSTEM_INODE, | ||
497 | 0); | ||
498 | #else | 503 | #else |
499 | alloc_inode = ocfs2_get_system_file_inode(osb, | 504 | slot = osb->slot_num; |
500 | EXTENT_ALLOC_SYSTEM_INODE, | ||
501 | osb->slot_num); | ||
502 | #endif | 505 | #endif |
503 | if (!alloc_inode) { | ||
504 | status = -ENOMEM; | ||
505 | mlog_errno(status); | ||
506 | goto bail; | ||
507 | } | ||
508 | 506 | ||
509 | (*ac)->ac_inode = igrab(alloc_inode); | ||
510 | (*ac)->ac_group_search = ocfs2_block_group_search; | 507 | (*ac)->ac_group_search = ocfs2_block_group_search; |
511 | 508 | ||
512 | status = ocfs2_reserve_suballoc_bits(osb, (*ac)); | 509 | status = ocfs2_reserve_suballoc_bits(osb, (*ac), |
510 | EXTENT_ALLOC_SYSTEM_INODE, slot); | ||
513 | if (status < 0) { | 511 | if (status < 0) { |
514 | if (status != -ENOSPC) | 512 | if (status != -ENOSPC) |
515 | mlog_errno(status); | 513 | mlog_errno(status); |
@@ -523,21 +521,16 @@ bail: | |||
523 | *ac = NULL; | 521 | *ac = NULL; |
524 | } | 522 | } |
525 | 523 | ||
526 | if (alloc_inode) | ||
527 | iput(alloc_inode); | ||
528 | |||
529 | mlog_exit(status); | 524 | mlog_exit(status); |
530 | return status; | 525 | return status; |
531 | } | 526 | } |
532 | 527 | ||
533 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | 528 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, |
534 | struct ocfs2_journal_handle *handle, | ||
535 | struct ocfs2_alloc_context **ac) | 529 | struct ocfs2_alloc_context **ac) |
536 | { | 530 | { |
537 | int status; | 531 | int status; |
538 | struct inode *alloc_inode = NULL; | ||
539 | 532 | ||
540 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 533 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
541 | if (!(*ac)) { | 534 | if (!(*ac)) { |
542 | status = -ENOMEM; | 535 | status = -ENOMEM; |
543 | mlog_errno(status); | 536 | mlog_errno(status); |
@@ -545,22 +538,13 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | |||
545 | } | 538 | } |
546 | 539 | ||
547 | (*ac)->ac_bits_wanted = 1; | 540 | (*ac)->ac_bits_wanted = 1; |
548 | (*ac)->ac_handle = handle; | ||
549 | (*ac)->ac_which = OCFS2_AC_USE_INODE; | 541 | (*ac)->ac_which = OCFS2_AC_USE_INODE; |
550 | 542 | ||
551 | alloc_inode = ocfs2_get_system_file_inode(osb, | ||
552 | INODE_ALLOC_SYSTEM_INODE, | ||
553 | osb->slot_num); | ||
554 | if (!alloc_inode) { | ||
555 | status = -ENOMEM; | ||
556 | mlog_errno(status); | ||
557 | goto bail; | ||
558 | } | ||
559 | |||
560 | (*ac)->ac_inode = igrab(alloc_inode); | ||
561 | (*ac)->ac_group_search = ocfs2_block_group_search; | 543 | (*ac)->ac_group_search = ocfs2_block_group_search; |
562 | 544 | ||
563 | status = ocfs2_reserve_suballoc_bits(osb, *ac); | 545 | status = ocfs2_reserve_suballoc_bits(osb, *ac, |
546 | INODE_ALLOC_SYSTEM_INODE, | ||
547 | osb->slot_num); | ||
564 | if (status < 0) { | 548 | if (status < 0) { |
565 | if (status != -ENOSPC) | 549 | if (status != -ENOSPC) |
566 | mlog_errno(status); | 550 | mlog_errno(status); |
@@ -574,9 +558,6 @@ bail: | |||
574 | *ac = NULL; | 558 | *ac = NULL; |
575 | } | 559 | } |
576 | 560 | ||
577 | if (alloc_inode) | ||
578 | iput(alloc_inode); | ||
579 | |||
580 | mlog_exit(status); | 561 | mlog_exit(status); |
581 | return status; | 562 | return status; |
582 | } | 563 | } |
@@ -588,20 +569,17 @@ int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb, | |||
588 | { | 569 | { |
589 | int status; | 570 | int status; |
590 | 571 | ||
591 | ac->ac_inode = ocfs2_get_system_file_inode(osb, | ||
592 | GLOBAL_BITMAP_SYSTEM_INODE, | ||
593 | OCFS2_INVALID_SLOT); | ||
594 | if (!ac->ac_inode) { | ||
595 | status = -EINVAL; | ||
596 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); | ||
597 | goto bail; | ||
598 | } | ||
599 | ac->ac_which = OCFS2_AC_USE_MAIN; | 572 | ac->ac_which = OCFS2_AC_USE_MAIN; |
600 | ac->ac_group_search = ocfs2_cluster_group_search; | 573 | ac->ac_group_search = ocfs2_cluster_group_search; |
601 | 574 | ||
602 | status = ocfs2_reserve_suballoc_bits(osb, ac); | 575 | status = ocfs2_reserve_suballoc_bits(osb, ac, |
603 | if (status < 0 && status != -ENOSPC) | 576 | GLOBAL_BITMAP_SYSTEM_INODE, |
577 | OCFS2_INVALID_SLOT); | ||
578 | if (status < 0 && status != -ENOSPC) { | ||
604 | mlog_errno(status); | 579 | mlog_errno(status); |
580 | goto bail; | ||
581 | } | ||
582 | |||
605 | bail: | 583 | bail: |
606 | return status; | 584 | return status; |
607 | } | 585 | } |
@@ -610,7 +588,6 @@ bail: | |||
610 | * use so we figure it out for them, but unfortunately this clutters | 588 | * use so we figure it out for them, but unfortunately this clutters |
611 | * things a bit. */ | 589 | * things a bit. */ |
612 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, | 590 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, |
613 | struct ocfs2_journal_handle *handle, | ||
614 | u32 bits_wanted, | 591 | u32 bits_wanted, |
615 | struct ocfs2_alloc_context **ac) | 592 | struct ocfs2_alloc_context **ac) |
616 | { | 593 | { |
@@ -618,9 +595,7 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb, | |||
618 | 595 | ||
619 | mlog_entry_void(); | 596 | mlog_entry_void(); |
620 | 597 | ||
621 | BUG_ON(!handle); | 598 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
622 | |||
623 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | ||
624 | if (!(*ac)) { | 599 | if (!(*ac)) { |
625 | status = -ENOMEM; | 600 | status = -ENOMEM; |
626 | mlog_errno(status); | 601 | mlog_errno(status); |
@@ -628,12 +603,10 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb, | |||
628 | } | 603 | } |
629 | 604 | ||
630 | (*ac)->ac_bits_wanted = bits_wanted; | 605 | (*ac)->ac_bits_wanted = bits_wanted; |
631 | (*ac)->ac_handle = handle; | ||
632 | 606 | ||
633 | status = -ENOSPC; | 607 | status = -ENOSPC; |
634 | if (ocfs2_alloc_should_use_local(osb, bits_wanted)) { | 608 | if (ocfs2_alloc_should_use_local(osb, bits_wanted)) { |
635 | status = ocfs2_reserve_local_alloc_bits(osb, | 609 | status = ocfs2_reserve_local_alloc_bits(osb, |
636 | handle, | ||
637 | bits_wanted, | 610 | bits_wanted, |
638 | *ac); | 611 | *ac); |
639 | if ((status < 0) && (status != -ENOSPC)) { | 612 | if ((status < 0) && (status != -ENOSPC)) { |
@@ -774,7 +747,7 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | |||
774 | return status; | 747 | return status; |
775 | } | 748 | } |
776 | 749 | ||
777 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, | 750 | static inline int ocfs2_block_group_set_bits(handle_t *handle, |
778 | struct inode *alloc_inode, | 751 | struct inode *alloc_inode, |
779 | struct ocfs2_group_desc *bg, | 752 | struct ocfs2_group_desc *bg, |
780 | struct buffer_head *group_bh, | 753 | struct buffer_head *group_bh, |
@@ -845,7 +818,7 @@ static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl) | |||
845 | return best; | 818 | return best; |
846 | } | 819 | } |
847 | 820 | ||
848 | static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | 821 | static int ocfs2_relink_block_group(handle_t *handle, |
849 | struct inode *alloc_inode, | 822 | struct inode *alloc_inode, |
850 | struct buffer_head *fe_bh, | 823 | struct buffer_head *fe_bh, |
851 | struct buffer_head *bg_bh, | 824 | struct buffer_head *bg_bh, |
@@ -1025,7 +998,7 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
1025 | } | 998 | } |
1026 | 999 | ||
1027 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, | 1000 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, |
1028 | struct ocfs2_journal_handle *handle, | 1001 | handle_t *handle, |
1029 | struct buffer_head *di_bh, | 1002 | struct buffer_head *di_bh, |
1030 | u32 num_bits, | 1003 | u32 num_bits, |
1031 | u16 chain) | 1004 | u16 chain) |
@@ -1055,6 +1028,7 @@ out: | |||
1055 | } | 1028 | } |
1056 | 1029 | ||
1057 | static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | 1030 | static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, |
1031 | handle_t *handle, | ||
1058 | u32 bits_wanted, | 1032 | u32 bits_wanted, |
1059 | u32 min_bits, | 1033 | u32 min_bits, |
1060 | u16 *bit_off, | 1034 | u16 *bit_off, |
@@ -1067,7 +1041,6 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1067 | struct buffer_head *group_bh = NULL; | 1041 | struct buffer_head *group_bh = NULL; |
1068 | struct ocfs2_group_desc *gd; | 1042 | struct ocfs2_group_desc *gd; |
1069 | struct inode *alloc_inode = ac->ac_inode; | 1043 | struct inode *alloc_inode = ac->ac_inode; |
1070 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
1071 | 1044 | ||
1072 | ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, | 1045 | ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, |
1073 | &group_bh, OCFS2_BH_CACHED, alloc_inode); | 1046 | &group_bh, OCFS2_BH_CACHED, alloc_inode); |
@@ -1115,6 +1088,7 @@ out: | |||
1115 | } | 1088 | } |
1116 | 1089 | ||
1117 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | 1090 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, |
1091 | handle_t *handle, | ||
1118 | u32 bits_wanted, | 1092 | u32 bits_wanted, |
1119 | u32 min_bits, | 1093 | u32 min_bits, |
1120 | u16 *bit_off, | 1094 | u16 *bit_off, |
@@ -1126,7 +1100,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1126 | u16 chain, tmp_bits; | 1100 | u16 chain, tmp_bits; |
1127 | u32 tmp_used; | 1101 | u32 tmp_used; |
1128 | u64 next_group; | 1102 | u64 next_group; |
1129 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
1130 | struct inode *alloc_inode = ac->ac_inode; | 1103 | struct inode *alloc_inode = ac->ac_inode; |
1131 | struct buffer_head *group_bh = NULL; | 1104 | struct buffer_head *group_bh = NULL; |
1132 | struct buffer_head *prev_group_bh = NULL; | 1105 | struct buffer_head *prev_group_bh = NULL; |
@@ -1272,6 +1245,7 @@ bail: | |||
1272 | /* will give out up to bits_wanted contiguous bits. */ | 1245 | /* will give out up to bits_wanted contiguous bits. */ |
1273 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | 1246 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, |
1274 | struct ocfs2_alloc_context *ac, | 1247 | struct ocfs2_alloc_context *ac, |
1248 | handle_t *handle, | ||
1275 | u32 bits_wanted, | 1249 | u32 bits_wanted, |
1276 | u32 min_bits, | 1250 | u32 min_bits, |
1277 | u16 *bit_off, | 1251 | u16 *bit_off, |
@@ -1313,8 +1287,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1313 | * by jumping straight to the most recently used | 1287 | * by jumping straight to the most recently used |
1314 | * allocation group. This helps us mantain some | 1288 | * allocation group. This helps us mantain some |
1315 | * contiguousness across allocations. */ | 1289 | * contiguousness across allocations. */ |
1316 | status = ocfs2_search_one_group(ac, bits_wanted, min_bits, | 1290 | status = ocfs2_search_one_group(ac, handle, bits_wanted, |
1317 | bit_off, num_bits, | 1291 | min_bits, bit_off, num_bits, |
1318 | hint_blkno, &bits_left); | 1292 | hint_blkno, &bits_left); |
1319 | if (!status) { | 1293 | if (!status) { |
1320 | /* Be careful to update *bg_blkno here as the | 1294 | /* Be careful to update *bg_blkno here as the |
@@ -1336,7 +1310,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1336 | ac->ac_chain = victim; | 1310 | ac->ac_chain = victim; |
1337 | ac->ac_allow_chain_relink = 1; | 1311 | ac->ac_allow_chain_relink = 1; |
1338 | 1312 | ||
1339 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, | 1313 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, bit_off, |
1340 | num_bits, bg_blkno, &bits_left); | 1314 | num_bits, bg_blkno, &bits_left); |
1341 | if (!status) | 1315 | if (!status) |
1342 | goto set_hint; | 1316 | goto set_hint; |
@@ -1360,7 +1334,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1360 | continue; | 1334 | continue; |
1361 | 1335 | ||
1362 | ac->ac_chain = i; | 1336 | ac->ac_chain = i; |
1363 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, | 1337 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
1364 | bit_off, num_bits, bg_blkno, | 1338 | bit_off, num_bits, bg_blkno, |
1365 | &bits_left); | 1339 | &bits_left); |
1366 | if (!status) | 1340 | if (!status) |
@@ -1388,7 +1362,7 @@ bail: | |||
1388 | } | 1362 | } |
1389 | 1363 | ||
1390 | int ocfs2_claim_metadata(struct ocfs2_super *osb, | 1364 | int ocfs2_claim_metadata(struct ocfs2_super *osb, |
1391 | struct ocfs2_journal_handle *handle, | 1365 | handle_t *handle, |
1392 | struct ocfs2_alloc_context *ac, | 1366 | struct ocfs2_alloc_context *ac, |
1393 | u32 bits_wanted, | 1367 | u32 bits_wanted, |
1394 | u16 *suballoc_bit_start, | 1368 | u16 *suballoc_bit_start, |
@@ -1401,10 +1375,10 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb, | |||
1401 | BUG_ON(!ac); | 1375 | BUG_ON(!ac); |
1402 | BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted)); | 1376 | BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted)); |
1403 | BUG_ON(ac->ac_which != OCFS2_AC_USE_META); | 1377 | BUG_ON(ac->ac_which != OCFS2_AC_USE_META); |
1404 | BUG_ON(ac->ac_handle != handle); | ||
1405 | 1378 | ||
1406 | status = ocfs2_claim_suballoc_bits(osb, | 1379 | status = ocfs2_claim_suballoc_bits(osb, |
1407 | ac, | 1380 | ac, |
1381 | handle, | ||
1408 | bits_wanted, | 1382 | bits_wanted, |
1409 | 1, | 1383 | 1, |
1410 | suballoc_bit_start, | 1384 | suballoc_bit_start, |
@@ -1425,7 +1399,7 @@ bail: | |||
1425 | } | 1399 | } |
1426 | 1400 | ||
1427 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 1401 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
1428 | struct ocfs2_journal_handle *handle, | 1402 | handle_t *handle, |
1429 | struct ocfs2_alloc_context *ac, | 1403 | struct ocfs2_alloc_context *ac, |
1430 | u16 *suballoc_bit, | 1404 | u16 *suballoc_bit, |
1431 | u64 *fe_blkno) | 1405 | u64 *fe_blkno) |
@@ -1440,10 +1414,10 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb, | |||
1440 | BUG_ON(ac->ac_bits_given != 0); | 1414 | BUG_ON(ac->ac_bits_given != 0); |
1441 | BUG_ON(ac->ac_bits_wanted != 1); | 1415 | BUG_ON(ac->ac_bits_wanted != 1); |
1442 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); | 1416 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); |
1443 | BUG_ON(ac->ac_handle != handle); | ||
1444 | 1417 | ||
1445 | status = ocfs2_claim_suballoc_bits(osb, | 1418 | status = ocfs2_claim_suballoc_bits(osb, |
1446 | ac, | 1419 | ac, |
1420 | handle, | ||
1447 | 1, | 1421 | 1, |
1448 | 1, | 1422 | 1, |
1449 | suballoc_bit, | 1423 | suballoc_bit, |
@@ -1528,7 +1502,7 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode, | |||
1528 | * of any size. | 1502 | * of any size. |
1529 | */ | 1503 | */ |
1530 | int ocfs2_claim_clusters(struct ocfs2_super *osb, | 1504 | int ocfs2_claim_clusters(struct ocfs2_super *osb, |
1531 | struct ocfs2_journal_handle *handle, | 1505 | handle_t *handle, |
1532 | struct ocfs2_alloc_context *ac, | 1506 | struct ocfs2_alloc_context *ac, |
1533 | u32 min_clusters, | 1507 | u32 min_clusters, |
1534 | u32 *cluster_start, | 1508 | u32 *cluster_start, |
@@ -1546,7 +1520,6 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
1546 | 1520 | ||
1547 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL | 1521 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL |
1548 | && ac->ac_which != OCFS2_AC_USE_MAIN); | 1522 | && ac->ac_which != OCFS2_AC_USE_MAIN); |
1549 | BUG_ON(ac->ac_handle != handle); | ||
1550 | 1523 | ||
1551 | if (ac->ac_which == OCFS2_AC_USE_LOCAL) { | 1524 | if (ac->ac_which == OCFS2_AC_USE_LOCAL) { |
1552 | status = ocfs2_claim_local_alloc_bits(osb, | 1525 | status = ocfs2_claim_local_alloc_bits(osb, |
@@ -1572,6 +1545,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
1572 | 1545 | ||
1573 | status = ocfs2_claim_suballoc_bits(osb, | 1546 | status = ocfs2_claim_suballoc_bits(osb, |
1574 | ac, | 1547 | ac, |
1548 | handle, | ||
1575 | bits_wanted, | 1549 | bits_wanted, |
1576 | min_clusters, | 1550 | min_clusters, |
1577 | &bg_bit_off, | 1551 | &bg_bit_off, |
@@ -1598,7 +1572,7 @@ bail: | |||
1598 | return status; | 1572 | return status; |
1599 | } | 1573 | } |
1600 | 1574 | ||
1601 | static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, | 1575 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, |
1602 | struct inode *alloc_inode, | 1576 | struct inode *alloc_inode, |
1603 | struct ocfs2_group_desc *bg, | 1577 | struct ocfs2_group_desc *bg, |
1604 | struct buffer_head *group_bh, | 1578 | struct buffer_head *group_bh, |
@@ -1653,7 +1627,7 @@ bail: | |||
1653 | /* | 1627 | /* |
1654 | * expects the suballoc inode to already be locked. | 1628 | * expects the suballoc inode to already be locked. |
1655 | */ | 1629 | */ |
1656 | static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, | 1630 | static int ocfs2_free_suballoc_bits(handle_t *handle, |
1657 | struct inode *alloc_inode, | 1631 | struct inode *alloc_inode, |
1658 | struct buffer_head *alloc_bh, | 1632 | struct buffer_head *alloc_bh, |
1659 | unsigned int start_bit, | 1633 | unsigned int start_bit, |
@@ -1737,7 +1711,7 @@ static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit) | |||
1737 | return group; | 1711 | return group; |
1738 | } | 1712 | } |
1739 | 1713 | ||
1740 | int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | 1714 | int ocfs2_free_dinode(handle_t *handle, |
1741 | struct inode *inode_alloc_inode, | 1715 | struct inode *inode_alloc_inode, |
1742 | struct buffer_head *inode_alloc_bh, | 1716 | struct buffer_head *inode_alloc_bh, |
1743 | struct ocfs2_dinode *di) | 1717 | struct ocfs2_dinode *di) |
@@ -1750,7 +1724,7 @@ int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | |||
1750 | inode_alloc_bh, bit, bg_blkno, 1); | 1724 | inode_alloc_bh, bit, bg_blkno, 1); |
1751 | } | 1725 | } |
1752 | 1726 | ||
1753 | int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | 1727 | int ocfs2_free_extent_block(handle_t *handle, |
1754 | struct inode *eb_alloc_inode, | 1728 | struct inode *eb_alloc_inode, |
1755 | struct buffer_head *eb_alloc_bh, | 1729 | struct buffer_head *eb_alloc_bh, |
1756 | struct ocfs2_extent_block *eb) | 1730 | struct ocfs2_extent_block *eb) |
@@ -1763,7 +1737,7 @@ int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | |||
1763 | bit, bg_blkno, 1); | 1737 | bit, bg_blkno, 1); |
1764 | } | 1738 | } |
1765 | 1739 | ||
1766 | int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, | 1740 | int ocfs2_free_clusters(handle_t *handle, |
1767 | struct inode *bitmap_inode, | 1741 | struct inode *bitmap_inode, |
1768 | struct buffer_head *bitmap_bh, | 1742 | struct buffer_head *bitmap_bh, |
1769 | u64 start_blk, | 1743 | u64 start_blk, |
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index c787838d1052..1a3c94cb9250 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -43,7 +43,6 @@ struct ocfs2_alloc_context { | |||
43 | #define OCFS2_AC_USE_INODE 3 | 43 | #define OCFS2_AC_USE_INODE 3 |
44 | #define OCFS2_AC_USE_META 4 | 44 | #define OCFS2_AC_USE_META 4 |
45 | u32 ac_which; | 45 | u32 ac_which; |
46 | struct ocfs2_journal_handle *ac_handle; | ||
47 | 46 | ||
48 | /* these are used by the chain search */ | 47 | /* these are used by the chain search */ |
49 | u16 ac_chain; | 48 | u16 ac_chain; |
@@ -60,45 +59,42 @@ static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac) | |||
60 | } | 59 | } |
61 | 60 | ||
62 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | 61 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, |
63 | struct ocfs2_journal_handle *handle, | ||
64 | struct ocfs2_dinode *fe, | 62 | struct ocfs2_dinode *fe, |
65 | struct ocfs2_alloc_context **ac); | 63 | struct ocfs2_alloc_context **ac); |
66 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | 64 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, |
67 | struct ocfs2_journal_handle *handle, | ||
68 | struct ocfs2_alloc_context **ac); | 65 | struct ocfs2_alloc_context **ac); |
69 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, | 66 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, |
70 | struct ocfs2_journal_handle *handle, | ||
71 | u32 bits_wanted, | 67 | u32 bits_wanted, |
72 | struct ocfs2_alloc_context **ac); | 68 | struct ocfs2_alloc_context **ac); |
73 | 69 | ||
74 | int ocfs2_claim_metadata(struct ocfs2_super *osb, | 70 | int ocfs2_claim_metadata(struct ocfs2_super *osb, |
75 | struct ocfs2_journal_handle *handle, | 71 | handle_t *handle, |
76 | struct ocfs2_alloc_context *ac, | 72 | struct ocfs2_alloc_context *ac, |
77 | u32 bits_wanted, | 73 | u32 bits_wanted, |
78 | u16 *suballoc_bit_start, | 74 | u16 *suballoc_bit_start, |
79 | u32 *num_bits, | 75 | u32 *num_bits, |
80 | u64 *blkno_start); | 76 | u64 *blkno_start); |
81 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 77 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
82 | struct ocfs2_journal_handle *handle, | 78 | handle_t *handle, |
83 | struct ocfs2_alloc_context *ac, | 79 | struct ocfs2_alloc_context *ac, |
84 | u16 *suballoc_bit, | 80 | u16 *suballoc_bit, |
85 | u64 *fe_blkno); | 81 | u64 *fe_blkno); |
86 | int ocfs2_claim_clusters(struct ocfs2_super *osb, | 82 | int ocfs2_claim_clusters(struct ocfs2_super *osb, |
87 | struct ocfs2_journal_handle *handle, | 83 | handle_t *handle, |
88 | struct ocfs2_alloc_context *ac, | 84 | struct ocfs2_alloc_context *ac, |
89 | u32 min_clusters, | 85 | u32 min_clusters, |
90 | u32 *cluster_start, | 86 | u32 *cluster_start, |
91 | u32 *num_clusters); | 87 | u32 *num_clusters); |
92 | 88 | ||
93 | int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | 89 | int ocfs2_free_dinode(handle_t *handle, |
94 | struct inode *inode_alloc_inode, | 90 | struct inode *inode_alloc_inode, |
95 | struct buffer_head *inode_alloc_bh, | 91 | struct buffer_head *inode_alloc_bh, |
96 | struct ocfs2_dinode *di); | 92 | struct ocfs2_dinode *di); |
97 | int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | 93 | int ocfs2_free_extent_block(handle_t *handle, |
98 | struct inode *eb_alloc_inode, | 94 | struct inode *eb_alloc_inode, |
99 | struct buffer_head *eb_alloc_bh, | 95 | struct buffer_head *eb_alloc_bh, |
100 | struct ocfs2_extent_block *eb); | 96 | struct ocfs2_extent_block *eb); |
101 | int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, | 97 | int ocfs2_free_clusters(handle_t *handle, |
102 | struct inode *bitmap_inode, | 98 | struct inode *bitmap_inode, |
103 | struct buffer_head *bitmap_bh, | 99 | struct buffer_head *bitmap_bh, |
104 | u64 start_blk, | 100 | u64 start_blk, |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 76b46ebbb10c..6e300a88a47e 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -68,9 +68,7 @@ | |||
68 | 68 | ||
69 | #include "buffer_head_io.h" | 69 | #include "buffer_head_io.h" |
70 | 70 | ||
71 | static kmem_cache_t *ocfs2_inode_cachep = NULL; | 71 | static struct kmem_cache *ocfs2_inode_cachep = NULL; |
72 | |||
73 | kmem_cache_t *ocfs2_lock_cache = NULL; | ||
74 | 72 | ||
75 | /* OCFS2 needs to schedule several differnt types of work which | 73 | /* OCFS2 needs to schedule several differnt types of work which |
76 | * require cluster locking, disk I/O, recovery waits, etc. Since these | 74 | * require cluster locking, disk I/O, recovery waits, etc. Since these |
@@ -141,6 +139,7 @@ enum { | |||
141 | Opt_hb_local, | 139 | Opt_hb_local, |
142 | Opt_data_ordered, | 140 | Opt_data_ordered, |
143 | Opt_data_writeback, | 141 | Opt_data_writeback, |
142 | Opt_atime_quantum, | ||
144 | Opt_err, | 143 | Opt_err, |
145 | }; | 144 | }; |
146 | 145 | ||
@@ -154,6 +153,7 @@ static match_table_t tokens = { | |||
154 | {Opt_hb_local, OCFS2_HB_LOCAL}, | 153 | {Opt_hb_local, OCFS2_HB_LOCAL}, |
155 | {Opt_data_ordered, "data=ordered"}, | 154 | {Opt_data_ordered, "data=ordered"}, |
156 | {Opt_data_writeback, "data=writeback"}, | 155 | {Opt_data_writeback, "data=writeback"}, |
156 | {Opt_atime_quantum, "atime_quantum=%u"}, | ||
157 | {Opt_err, NULL} | 157 | {Opt_err, NULL} |
158 | }; | 158 | }; |
159 | 159 | ||
@@ -303,7 +303,7 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb) | |||
303 | { | 303 | { |
304 | struct ocfs2_inode_info *oi; | 304 | struct ocfs2_inode_info *oi; |
305 | 305 | ||
306 | oi = kmem_cache_alloc(ocfs2_inode_cachep, SLAB_NOFS); | 306 | oi = kmem_cache_alloc(ocfs2_inode_cachep, GFP_NOFS); |
307 | if (!oi) | 307 | if (!oi) |
308 | return NULL; | 308 | return NULL; |
309 | 309 | ||
@@ -508,6 +508,27 @@ bail: | |||
508 | return status; | 508 | return status; |
509 | } | 509 | } |
510 | 510 | ||
511 | static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) | ||
512 | { | ||
513 | if (ocfs2_mount_local(osb)) { | ||
514 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
515 | mlog(ML_ERROR, "Cannot heartbeat on a locally " | ||
516 | "mounted device.\n"); | ||
517 | return -EINVAL; | ||
518 | } | ||
519 | } | ||
520 | |||
521 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | ||
522 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb)) { | ||
523 | mlog(ML_ERROR, "Heartbeat has to be started to mount " | ||
524 | "a read-write clustered device.\n"); | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
511 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | 532 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) |
512 | { | 533 | { |
513 | struct dentry *root; | 534 | struct dentry *root; |
@@ -516,16 +537,24 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
516 | struct inode *inode = NULL; | 537 | struct inode *inode = NULL; |
517 | struct ocfs2_super *osb = NULL; | 538 | struct ocfs2_super *osb = NULL; |
518 | struct buffer_head *bh = NULL; | 539 | struct buffer_head *bh = NULL; |
540 | char nodestr[8]; | ||
519 | 541 | ||
520 | mlog_entry("%p, %p, %i", sb, data, silent); | 542 | mlog_entry("%p, %p, %i", sb, data, silent); |
521 | 543 | ||
522 | /* for now we only have one cluster/node, make sure we see it | 544 | if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) { |
523 | * in the heartbeat universe */ | ||
524 | if (!o2hb_check_local_node_heartbeating()) { | ||
525 | status = -EINVAL; | 545 | status = -EINVAL; |
526 | goto read_super_error; | 546 | goto read_super_error; |
527 | } | 547 | } |
528 | 548 | ||
549 | /* for now we only have one cluster/node, make sure we see it | ||
550 | * in the heartbeat universe */ | ||
551 | if (parsed_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
552 | if (!o2hb_check_local_node_heartbeating()) { | ||
553 | status = -EINVAL; | ||
554 | goto read_super_error; | ||
555 | } | ||
556 | } | ||
557 | |||
529 | /* probe for superblock */ | 558 | /* probe for superblock */ |
530 | status = ocfs2_sb_probe(sb, &bh, §or_size); | 559 | status = ocfs2_sb_probe(sb, &bh, §or_size); |
531 | if (status < 0) { | 560 | if (status < 0) { |
@@ -541,11 +570,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
541 | } | 570 | } |
542 | brelse(bh); | 571 | brelse(bh); |
543 | bh = NULL; | 572 | bh = NULL; |
544 | |||
545 | if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) { | ||
546 | status = -EINVAL; | ||
547 | goto read_super_error; | ||
548 | } | ||
549 | osb->s_mount_opt = parsed_opt; | 573 | osb->s_mount_opt = parsed_opt; |
550 | 574 | ||
551 | sb->s_magic = OCFS2_SUPER_MAGIC; | 575 | sb->s_magic = OCFS2_SUPER_MAGIC; |
@@ -588,21 +612,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
588 | } | 612 | } |
589 | 613 | ||
590 | if (!ocfs2_is_hard_readonly(osb)) { | 614 | if (!ocfs2_is_hard_readonly(osb)) { |
591 | /* If this isn't a hard readonly mount, then we need | ||
592 | * to make sure that heartbeat is in a valid state, | ||
593 | * and that we mark ourselves soft readonly is -oro | ||
594 | * was specified. */ | ||
595 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | ||
596 | mlog(ML_ERROR, "No heartbeat for device (%s)\n", | ||
597 | sb->s_id); | ||
598 | status = -EINVAL; | ||
599 | goto read_super_error; | ||
600 | } | ||
601 | |||
602 | if (sb->s_flags & MS_RDONLY) | 615 | if (sb->s_flags & MS_RDONLY) |
603 | ocfs2_set_ro_flag(osb, 0); | 616 | ocfs2_set_ro_flag(osb, 0); |
604 | } | 617 | } |
605 | 618 | ||
619 | status = ocfs2_verify_heartbeat(osb); | ||
620 | if (status < 0) { | ||
621 | mlog_errno(status); | ||
622 | goto read_super_error; | ||
623 | } | ||
624 | |||
606 | osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, | 625 | osb->osb_debug_root = debugfs_create_dir(osb->uuid_str, |
607 | ocfs2_debugfs_root); | 626 | ocfs2_debugfs_root); |
608 | if (!osb->osb_debug_root) { | 627 | if (!osb->osb_debug_root) { |
@@ -635,9 +654,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
635 | 654 | ||
636 | ocfs2_complete_mount_recovery(osb); | 655 | ocfs2_complete_mount_recovery(osb); |
637 | 656 | ||
638 | printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) " | 657 | if (ocfs2_mount_local(osb)) |
658 | snprintf(nodestr, sizeof(nodestr), "local"); | ||
659 | else | ||
660 | snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num); | ||
661 | |||
662 | printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) " | ||
639 | "with %s data mode.\n", | 663 | "with %s data mode.\n", |
640 | osb->dev_str, osb->node_num, osb->slot_num, | 664 | osb->dev_str, nodestr, osb->slot_num, |
641 | osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" : | 665 | osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" : |
642 | "ordered"); | 666 | "ordered"); |
643 | 667 | ||
@@ -707,6 +731,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
707 | while ((p = strsep(&options, ",")) != NULL) { | 731 | while ((p = strsep(&options, ",")) != NULL) { |
708 | int token, option; | 732 | int token, option; |
709 | substring_t args[MAX_OPT_ARGS]; | 733 | substring_t args[MAX_OPT_ARGS]; |
734 | struct ocfs2_super * osb = OCFS2_SB(sb); | ||
710 | 735 | ||
711 | if (!*p) | 736 | if (!*p) |
712 | continue; | 737 | continue; |
@@ -747,6 +772,16 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
747 | case Opt_data_writeback: | 772 | case Opt_data_writeback: |
748 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; | 773 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; |
749 | break; | 774 | break; |
775 | case Opt_atime_quantum: | ||
776 | if (match_int(&args[0], &option)) { | ||
777 | status = 0; | ||
778 | goto bail; | ||
779 | } | ||
780 | if (option >= 0) | ||
781 | osb->s_atime_quantum = option; | ||
782 | else | ||
783 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
784 | break; | ||
750 | default: | 785 | default: |
751 | mlog(ML_ERROR, | 786 | mlog(ML_ERROR, |
752 | "Unrecognized mount option \"%s\" " | 787 | "Unrecognized mount option \"%s\" " |
@@ -867,7 +902,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
867 | goto bail; | 902 | goto bail; |
868 | } | 903 | } |
869 | 904 | ||
870 | status = ocfs2_meta_lock(inode, NULL, &bh, 0); | 905 | status = ocfs2_meta_lock(inode, &bh, 0); |
871 | if (status < 0) { | 906 | if (status < 0) { |
872 | mlog_errno(status); | 907 | mlog_errno(status); |
873 | goto bail; | 908 | goto bail; |
@@ -903,7 +938,7 @@ bail: | |||
903 | } | 938 | } |
904 | 939 | ||
905 | static void ocfs2_inode_init_once(void *data, | 940 | static void ocfs2_inode_init_once(void *data, |
906 | kmem_cache_t *cachep, | 941 | struct kmem_cache *cachep, |
907 | unsigned long flags) | 942 | unsigned long flags) |
908 | { | 943 | { |
909 | struct ocfs2_inode_info *oi = data; | 944 | struct ocfs2_inode_info *oi = data; |
@@ -914,9 +949,7 @@ static void ocfs2_inode_init_once(void *data, | |||
914 | oi->ip_open_count = 0; | 949 | oi->ip_open_count = 0; |
915 | spin_lock_init(&oi->ip_lock); | 950 | spin_lock_init(&oi->ip_lock); |
916 | ocfs2_extent_map_init(&oi->vfs_inode); | 951 | ocfs2_extent_map_init(&oi->vfs_inode); |
917 | INIT_LIST_HEAD(&oi->ip_handle_list); | ||
918 | INIT_LIST_HEAD(&oi->ip_io_markers); | 952 | INIT_LIST_HEAD(&oi->ip_io_markers); |
919 | oi->ip_handle = NULL; | ||
920 | oi->ip_created_trans = 0; | 953 | oi->ip_created_trans = 0; |
921 | oi->ip_last_trans = 0; | 954 | oi->ip_last_trans = 0; |
922 | oi->ip_dir_start_lookup = 0; | 955 | oi->ip_dir_start_lookup = 0; |
@@ -948,14 +981,6 @@ static int ocfs2_initialize_mem_caches(void) | |||
948 | if (!ocfs2_inode_cachep) | 981 | if (!ocfs2_inode_cachep) |
949 | return -ENOMEM; | 982 | return -ENOMEM; |
950 | 983 | ||
951 | ocfs2_lock_cache = kmem_cache_create("ocfs2_lock", | ||
952 | sizeof(struct ocfs2_journal_lock), | ||
953 | 0, | ||
954 | SLAB_HWCACHE_ALIGN, | ||
955 | NULL, NULL); | ||
956 | if (!ocfs2_lock_cache) | ||
957 | return -ENOMEM; | ||
958 | |||
959 | return 0; | 984 | return 0; |
960 | } | 985 | } |
961 | 986 | ||
@@ -963,11 +988,8 @@ static void ocfs2_free_mem_caches(void) | |||
963 | { | 988 | { |
964 | if (ocfs2_inode_cachep) | 989 | if (ocfs2_inode_cachep) |
965 | kmem_cache_destroy(ocfs2_inode_cachep); | 990 | kmem_cache_destroy(ocfs2_inode_cachep); |
966 | if (ocfs2_lock_cache) | ||
967 | kmem_cache_destroy(ocfs2_lock_cache); | ||
968 | 991 | ||
969 | ocfs2_inode_cachep = NULL; | 992 | ocfs2_inode_cachep = NULL; |
970 | ocfs2_lock_cache = NULL; | ||
971 | } | 993 | } |
972 | 994 | ||
973 | static int ocfs2_get_sector(struct super_block *sb, | 995 | static int ocfs2_get_sector(struct super_block *sb, |
@@ -1001,7 +1023,11 @@ static int ocfs2_fill_local_node_info(struct ocfs2_super *osb) | |||
1001 | 1023 | ||
1002 | /* XXX hold a ref on the node while mounte? easy enough, if | 1024 | /* XXX hold a ref on the node while mounte? easy enough, if |
1003 | * desirable. */ | 1025 | * desirable. */ |
1004 | osb->node_num = o2nm_this_node(); | 1026 | if (ocfs2_mount_local(osb)) |
1027 | osb->node_num = 0; | ||
1028 | else | ||
1029 | osb->node_num = o2nm_this_node(); | ||
1030 | |||
1005 | if (osb->node_num == O2NM_MAX_NODES) { | 1031 | if (osb->node_num == O2NM_MAX_NODES) { |
1006 | mlog(ML_ERROR, "could not find this host's node number\n"); | 1032 | mlog(ML_ERROR, "could not find this host's node number\n"); |
1007 | status = -ENOENT; | 1033 | status = -ENOENT; |
@@ -1086,6 +1112,9 @@ static int ocfs2_mount_volume(struct super_block *sb) | |||
1086 | goto leave; | 1112 | goto leave; |
1087 | } | 1113 | } |
1088 | 1114 | ||
1115 | if (ocfs2_mount_local(osb)) | ||
1116 | goto leave; | ||
1117 | |||
1089 | /* This should be sent *after* we recovered our journal as it | 1118 | /* This should be sent *after* we recovered our journal as it |
1090 | * will cause other nodes to unmark us as needing | 1119 | * will cause other nodes to unmark us as needing |
1091 | * recovery. However, we need to send it *before* dropping the | 1120 | * recovery. However, we need to send it *before* dropping the |
@@ -1116,6 +1145,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1116 | { | 1145 | { |
1117 | int tmp; | 1146 | int tmp; |
1118 | struct ocfs2_super *osb = NULL; | 1147 | struct ocfs2_super *osb = NULL; |
1148 | char nodestr[8]; | ||
1119 | 1149 | ||
1120 | mlog_entry("(0x%p)\n", sb); | 1150 | mlog_entry("(0x%p)\n", sb); |
1121 | 1151 | ||
@@ -1179,8 +1209,13 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1179 | 1209 | ||
1180 | atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); | 1210 | atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); |
1181 | 1211 | ||
1182 | printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %d)\n", | 1212 | if (ocfs2_mount_local(osb)) |
1183 | osb->dev_str, osb->node_num); | 1213 | snprintf(nodestr, sizeof(nodestr), "local"); |
1214 | else | ||
1215 | snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num); | ||
1216 | |||
1217 | printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n", | ||
1218 | osb->dev_str, nodestr); | ||
1184 | 1219 | ||
1185 | ocfs2_delete_osb(osb); | 1220 | ocfs2_delete_osb(osb); |
1186 | kfree(osb); | 1221 | kfree(osb); |
@@ -1196,7 +1231,7 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu | |||
1196 | 1231 | ||
1197 | BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN); | 1232 | BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN); |
1198 | 1233 | ||
1199 | osb->uuid_str = kcalloc(1, OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL); | 1234 | osb->uuid_str = kzalloc(OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL); |
1200 | if (osb->uuid_str == NULL) | 1235 | if (osb->uuid_str == NULL) |
1201 | return -ENOMEM; | 1236 | return -ENOMEM; |
1202 | 1237 | ||
@@ -1227,7 +1262,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1227 | 1262 | ||
1228 | mlog_entry_void(); | 1263 | mlog_entry_void(); |
1229 | 1264 | ||
1230 | osb = kcalloc(1, sizeof(struct ocfs2_super), GFP_KERNEL); | 1265 | osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL); |
1231 | if (!osb) { | 1266 | if (!osb) { |
1232 | status = -ENOMEM; | 1267 | status = -ENOMEM; |
1233 | mlog_errno(status); | 1268 | mlog_errno(status); |
@@ -1280,6 +1315,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1280 | init_waitqueue_head(&osb->checkpoint_event); | 1315 | init_waitqueue_head(&osb->checkpoint_event); |
1281 | atomic_set(&osb->needs_checkpoint, 0); | 1316 | atomic_set(&osb->needs_checkpoint, 0); |
1282 | 1317 | ||
1318 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
1319 | |||
1283 | osb->node_num = O2NM_INVALID_NODE_NUM; | 1320 | osb->node_num = O2NM_INVALID_NODE_NUM; |
1284 | osb->slot_num = OCFS2_INVALID_SLOT; | 1321 | osb->slot_num = OCFS2_INVALID_SLOT; |
1285 | 1322 | ||
@@ -1350,7 +1387,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1350 | */ | 1387 | */ |
1351 | /* initialize our journal structure */ | 1388 | /* initialize our journal structure */ |
1352 | 1389 | ||
1353 | journal = kcalloc(1, sizeof(struct ocfs2_journal), GFP_KERNEL); | 1390 | journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL); |
1354 | if (!journal) { | 1391 | if (!journal) { |
1355 | mlog(ML_ERROR, "unable to alloc journal\n"); | 1392 | mlog(ML_ERROR, "unable to alloc journal\n"); |
1356 | status = -ENOMEM; | 1393 | status = -ENOMEM; |
@@ -1365,7 +1402,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1365 | spin_lock_init(&journal->j_lock); | 1402 | spin_lock_init(&journal->j_lock); |
1366 | journal->j_trans_id = (unsigned long) 1; | 1403 | journal->j_trans_id = (unsigned long) 1; |
1367 | INIT_LIST_HEAD(&journal->j_la_cleanups); | 1404 | INIT_LIST_HEAD(&journal->j_la_cleanups); |
1368 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery, osb); | 1405 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); |
1369 | journal->j_state = OCFS2_JOURNAL_FREE; | 1406 | journal->j_state = OCFS2_JOURNAL_FREE; |
1370 | 1407 | ||
1371 | /* get some pseudo constants for clustersize bits */ | 1408 | /* get some pseudo constants for clustersize bits */ |
@@ -1536,6 +1573,7 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) | |||
1536 | { | 1573 | { |
1537 | int status = 0; | 1574 | int status = 0; |
1538 | int dirty; | 1575 | int dirty; |
1576 | int local; | ||
1539 | struct ocfs2_dinode *local_alloc = NULL; /* only used if we | 1577 | struct ocfs2_dinode *local_alloc = NULL; /* only used if we |
1540 | * recover | 1578 | * recover |
1541 | * ourselves. */ | 1579 | * ourselves. */ |
@@ -1563,8 +1601,10 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) | |||
1563 | "recovering volume.\n"); | 1601 | "recovering volume.\n"); |
1564 | } | 1602 | } |
1565 | 1603 | ||
1604 | local = ocfs2_mount_local(osb); | ||
1605 | |||
1566 | /* will play back anything left in the journal. */ | 1606 | /* will play back anything left in the journal. */ |
1567 | ocfs2_journal_load(osb->journal); | 1607 | ocfs2_journal_load(osb->journal, local); |
1568 | 1608 | ||
1569 | if (dirty) { | 1609 | if (dirty) { |
1570 | /* recover my local alloc if we didn't unmount cleanly. */ | 1610 | /* recover my local alloc if we didn't unmount cleanly. */ |
@@ -1674,7 +1714,7 @@ void __ocfs2_error(struct super_block *sb, | |||
1674 | va_list args; | 1714 | va_list args; |
1675 | 1715 | ||
1676 | va_start(args, fmt); | 1716 | va_start(args, fmt); |
1677 | vsprintf(error_buf, fmt, args); | 1717 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1678 | va_end(args); | 1718 | va_end(args); |
1679 | 1719 | ||
1680 | /* Not using mlog here because we want to show the actual | 1720 | /* Not using mlog here because we want to show the actual |
@@ -1695,7 +1735,7 @@ void __ocfs2_abort(struct super_block* sb, | |||
1695 | va_list args; | 1735 | va_list args; |
1696 | 1736 | ||
1697 | va_start(args, fmt); | 1737 | va_start(args, fmt); |
1698 | vsprintf(error_buf, fmt, args); | 1738 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1699 | va_end(args); | 1739 | va_end(args); |
1700 | 1740 | ||
1701 | printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n", | 1741 | printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n", |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index c0f68aa6c175..957d6878b03e 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -126,6 +126,10 @@ static int ocfs2_readlink(struct dentry *dentry, | |||
126 | goto out; | 126 | goto out; |
127 | } | 127 | } |
128 | 128 | ||
129 | /* | ||
130 | * Without vfsmount we can't update atime now, | ||
131 | * but we will update atime here ultimately. | ||
132 | */ | ||
129 | ret = vfs_readlink(dentry, buffer, buflen, link); | 133 | ret = vfs_readlink(dentry, buffer, buflen, link); |
130 | 134 | ||
131 | brelse(bh); | 135 | brelse(bh); |
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c index 9707ed7a3206..39814b900fc0 100644 --- a/fs/ocfs2/uptodate.c +++ b/fs/ocfs2/uptodate.c | |||
@@ -69,7 +69,7 @@ struct ocfs2_meta_cache_item { | |||
69 | sector_t c_block; | 69 | sector_t c_block; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static kmem_cache_t *ocfs2_uptodate_cachep = NULL; | 72 | static struct kmem_cache *ocfs2_uptodate_cachep = NULL; |
73 | 73 | ||
74 | void ocfs2_metadata_cache_init(struct inode *inode) | 74 | void ocfs2_metadata_cache_init(struct inode *inode) |
75 | { | 75 | { |
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c index 5b4dca79990b..0afd8b9af70f 100644 --- a/fs/ocfs2/vote.c +++ b/fs/ocfs2/vote.c | |||
@@ -479,7 +479,7 @@ static struct ocfs2_net_wait_ctxt *ocfs2_new_net_wait_ctxt(unsigned int response | |||
479 | { | 479 | { |
480 | struct ocfs2_net_wait_ctxt *w; | 480 | struct ocfs2_net_wait_ctxt *w; |
481 | 481 | ||
482 | w = kcalloc(1, sizeof(*w), GFP_NOFS); | 482 | w = kzalloc(sizeof(*w), GFP_NOFS); |
483 | if (!w) { | 483 | if (!w) { |
484 | mlog_errno(-ENOMEM); | 484 | mlog_errno(-ENOMEM); |
485 | goto bail; | 485 | goto bail; |
@@ -642,7 +642,7 @@ static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb, | |||
642 | 642 | ||
643 | BUG_ON(!ocfs2_is_valid_vote_request(type)); | 643 | BUG_ON(!ocfs2_is_valid_vote_request(type)); |
644 | 644 | ||
645 | request = kcalloc(1, sizeof(*request), GFP_NOFS); | 645 | request = kzalloc(sizeof(*request), GFP_NOFS); |
646 | if (!request) { | 646 | if (!request) { |
647 | mlog_errno(-ENOMEM); | 647 | mlog_errno(-ENOMEM); |
648 | } else { | 648 | } else { |
@@ -1000,6 +1000,9 @@ int ocfs2_register_net_handlers(struct ocfs2_super *osb) | |||
1000 | { | 1000 | { |
1001 | int status = 0; | 1001 | int status = 0; |
1002 | 1002 | ||
1003 | if (ocfs2_mount_local(osb)) | ||
1004 | return 0; | ||
1005 | |||
1003 | status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE, | 1006 | status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE, |
1004 | osb->net_key, | 1007 | osb->net_key, |
1005 | sizeof(struct ocfs2_response_msg), | 1008 | sizeof(struct ocfs2_response_msg), |
@@ -165,7 +165,7 @@ asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf) | |||
165 | file = fget(fd); | 165 | file = fget(fd); |
166 | if (!file) | 166 | if (!file) |
167 | goto out; | 167 | goto out; |
168 | error = vfs_statfs_native(file->f_dentry, &tmp); | 168 | error = vfs_statfs_native(file->f_path.dentry, &tmp); |
169 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 169 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
170 | error = -EFAULT; | 170 | error = -EFAULT; |
171 | fput(file); | 171 | fput(file); |
@@ -186,7 +186,7 @@ asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user | |||
186 | file = fget(fd); | 186 | file = fget(fd); |
187 | if (!file) | 187 | if (!file) |
188 | goto out; | 188 | goto out; |
189 | error = vfs_statfs64(file->f_dentry, &tmp); | 189 | error = vfs_statfs64(file->f_path.dentry, &tmp); |
190 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | 190 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) |
191 | error = -EFAULT; | 191 | error = -EFAULT; |
192 | fput(file); | 192 | fput(file); |
@@ -302,7 +302,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
302 | if (file->f_flags & O_LARGEFILE) | 302 | if (file->f_flags & O_LARGEFILE) |
303 | small = 0; | 303 | small = 0; |
304 | 304 | ||
305 | dentry = file->f_dentry; | 305 | dentry = file->f_path.dentry; |
306 | inode = dentry->d_inode; | 306 | inode = dentry->d_inode; |
307 | error = -EINVAL; | 307 | error = -EINVAL; |
308 | if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) | 308 | if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE)) |
@@ -448,8 +448,8 @@ asmlinkage long sys_fchdir(unsigned int fd) | |||
448 | if (!file) | 448 | if (!file) |
449 | goto out; | 449 | goto out; |
450 | 450 | ||
451 | dentry = file->f_dentry; | 451 | dentry = file->f_path.dentry; |
452 | mnt = file->f_vfsmnt; | 452 | mnt = file->f_path.mnt; |
453 | inode = dentry->d_inode; | 453 | inode = dentry->d_inode; |
454 | 454 | ||
455 | error = -ENOTDIR; | 455 | error = -ENOTDIR; |
@@ -503,7 +503,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
503 | if (!file) | 503 | if (!file) |
504 | goto out; | 504 | goto out; |
505 | 505 | ||
506 | dentry = file->f_dentry; | 506 | dentry = file->f_path.dentry; |
507 | inode = dentry->d_inode; | 507 | inode = dentry->d_inode; |
508 | 508 | ||
509 | audit_inode(NULL, inode); | 509 | audit_inode(NULL, inode); |
@@ -662,7 +662,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) | |||
662 | if (!file) | 662 | if (!file) |
663 | goto out; | 663 | goto out; |
664 | 664 | ||
665 | dentry = file->f_dentry; | 665 | dentry = file->f_path.dentry; |
666 | audit_inode(NULL, dentry->d_inode); | 666 | audit_inode(NULL, dentry->d_inode); |
667 | error = chown_common(dentry, user, group); | 667 | error = chown_common(dentry, user, group); |
668 | fput(file); | 668 | fput(file); |
@@ -688,8 +688,8 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
688 | } | 688 | } |
689 | 689 | ||
690 | f->f_mapping = inode->i_mapping; | 690 | f->f_mapping = inode->i_mapping; |
691 | f->f_dentry = dentry; | 691 | f->f_path.dentry = dentry; |
692 | f->f_vfsmnt = mnt; | 692 | f->f_path.mnt = mnt; |
693 | f->f_pos = 0; | 693 | f->f_pos = 0; |
694 | f->f_op = fops_get(inode->i_fop); | 694 | f->f_op = fops_get(inode->i_fop); |
695 | file_move(f, &inode->i_sb->s_files); | 695 | file_move(f, &inode->i_sb->s_files); |
@@ -723,8 +723,8 @@ cleanup_all: | |||
723 | if (f->f_mode & FMODE_WRITE) | 723 | if (f->f_mode & FMODE_WRITE) |
724 | put_write_access(inode); | 724 | put_write_access(inode); |
725 | file_kill(f); | 725 | file_kill(f); |
726 | f->f_dentry = NULL; | 726 | f->f_path.dentry = NULL; |
727 | f->f_vfsmnt = NULL; | 727 | f->f_path.mnt = NULL; |
728 | cleanup_file: | 728 | cleanup_file: |
729 | put_filp(f); | 729 | put_filp(f); |
730 | dput(dentry); | 730 | dput(dentry); |
@@ -822,7 +822,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) | |||
822 | /* Pick up the filp from the open intent */ | 822 | /* Pick up the filp from the open intent */ |
823 | filp = nd->intent.open.file; | 823 | filp = nd->intent.open.file; |
824 | /* Has the filesystem initialised the file for us? */ | 824 | /* Has the filesystem initialised the file for us? */ |
825 | if (filp->f_dentry == NULL) | 825 | if (filp->f_path.dentry == NULL) |
826 | filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL); | 826 | filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL); |
827 | else | 827 | else |
828 | path_release(nd); | 828 | path_release(nd); |
@@ -864,8 +864,7 @@ int get_unused_fd(void) | |||
864 | 864 | ||
865 | repeat: | 865 | repeat: |
866 | fdt = files_fdtable(files); | 866 | fdt = files_fdtable(files); |
867 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, | 867 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, |
868 | fdt->max_fdset, | ||
869 | files->next_fd); | 868 | files->next_fd); |
870 | 869 | ||
871 | /* | 870 | /* |
@@ -965,7 +964,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode) | |||
965 | put_unused_fd(fd); | 964 | put_unused_fd(fd); |
966 | fd = PTR_ERR(f); | 965 | fd = PTR_ERR(f); |
967 | } else { | 966 | } else { |
968 | fsnotify_open(f->f_dentry); | 967 | fsnotify_open(f->f_path.dentry); |
969 | fd_install(fd, f); | 968 | fd_install(fd, f); |
970 | } | 969 | } |
971 | } | 970 | } |
@@ -1087,6 +1086,7 @@ EXPORT_SYMBOL(sys_close); | |||
1087 | asmlinkage long sys_vhangup(void) | 1086 | asmlinkage long sys_vhangup(void) |
1088 | { | 1087 | { |
1089 | if (capable(CAP_SYS_TTY_CONFIG)) { | 1088 | if (capable(CAP_SYS_TTY_CONFIG)) { |
1089 | /* XXX: this needs locking */ | ||
1090 | tty_vhangup(current->signal->tty); | 1090 | tty_vhangup(current->signal->tty); |
1091 | return 0; | 1091 | return 0; |
1092 | } | 1092 | } |
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 592a6402e851..99c0bc37ba09 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -262,7 +262,7 @@ found: | |||
262 | 262 | ||
263 | static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 263 | static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
264 | { | 264 | { |
265 | struct inode *inode = filp->f_dentry->d_inode; | 265 | struct inode *inode = filp->f_path.dentry->d_inode; |
266 | struct op_inode_info *oi = OP_I(inode); | 266 | struct op_inode_info *oi = OP_I(inode); |
267 | struct device_node *dp = oi->u.node; | 267 | struct device_node *dp = oi->u.node; |
268 | struct device_node *child; | 268 | struct device_node *child; |
@@ -330,13 +330,13 @@ out: | |||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
332 | 332 | ||
333 | static kmem_cache_t *op_inode_cachep; | 333 | static struct kmem_cache *op_inode_cachep; |
334 | 334 | ||
335 | static struct inode *openprom_alloc_inode(struct super_block *sb) | 335 | static struct inode *openprom_alloc_inode(struct super_block *sb) |
336 | { | 336 | { |
337 | struct op_inode_info *oi; | 337 | struct op_inode_info *oi; |
338 | 338 | ||
339 | oi = kmem_cache_alloc(op_inode_cachep, SLAB_KERNEL); | 339 | oi = kmem_cache_alloc(op_inode_cachep, GFP_KERNEL); |
340 | if (!oi) | 340 | if (!oi) |
341 | return NULL; | 341 | return NULL; |
342 | 342 | ||
@@ -415,7 +415,7 @@ static struct file_system_type openprom_fs_type = { | |||
415 | .kill_sb = kill_anon_super, | 415 | .kill_sb = kill_anon_super, |
416 | }; | 416 | }; |
417 | 417 | ||
418 | static void op_inode_init_once(void *data, kmem_cache_t * cachep, unsigned long flags) | 418 | static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned long flags) |
419 | { | 419 | { |
420 | struct op_inode_info *oi = (struct op_inode_info *) data; | 420 | struct op_inode_info *oi = (struct op_inode_info *) data; |
421 | 421 | ||
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index e478f1941831..74552c60b671 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -194,7 +194,7 @@ config LDM_DEBUG | |||
194 | 194 | ||
195 | config SGI_PARTITION | 195 | config SGI_PARTITION |
196 | bool "SGI partition support" if PARTITION_ADVANCED | 196 | bool "SGI partition support" if PARTITION_ADVANCED |
197 | default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM200_PCI) && !CPU_LITTLE_ENDIAN)) | 197 | default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM) && !CPU_LITTLE_ENDIAN)) |
198 | help | 198 | help |
199 | Say Y here if you would like to be able to read the hard disk | 199 | Say Y here if you would like to be able to read the hard disk |
200 | partition table format used by SGI machines. | 200 | partition table format used by SGI machines. |
diff --git a/fs/partitions/amiga.c b/fs/partitions/amiga.c index 3068528890a6..9917a8c360f2 100644 --- a/fs/partitions/amiga.c +++ b/fs/partitions/amiga.c | |||
@@ -43,6 +43,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
43 | if (warn_no_part) | 43 | if (warn_no_part) |
44 | printk("Dev %s: unable to read RDB block %d\n", | 44 | printk("Dev %s: unable to read RDB block %d\n", |
45 | bdevname(bdev, b), blk); | 45 | bdevname(bdev, b), blk); |
46 | res = -1; | ||
46 | goto rdb_done; | 47 | goto rdb_done; |
47 | } | 48 | } |
48 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) | 49 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) |
@@ -79,6 +80,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
79 | if (warn_no_part) | 80 | if (warn_no_part) |
80 | printk("Dev %s: unable to read partition block %d\n", | 81 | printk("Dev %s: unable to read partition block %d\n", |
81 | bdevname(bdev, b), blk); | 82 | bdevname(bdev, b), blk); |
83 | res = -1; | ||
82 | goto rdb_done; | 84 | goto rdb_done; |
83 | } | 85 | } |
84 | pb = (struct PartitionBlock *)data; | 86 | pb = (struct PartitionBlock *)data; |
diff --git a/fs/partitions/atari.c b/fs/partitions/atari.c index 192a6adfdefd..1f3572d5b755 100644 --- a/fs/partitions/atari.c +++ b/fs/partitions/atari.c | |||
@@ -88,7 +88,7 @@ int atari_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
88 | if (!xrs) { | 88 | if (!xrs) { |
89 | printk (" block %ld read failed\n", partsect); | 89 | printk (" block %ld read failed\n", partsect); |
90 | put_dev_sector(sect); | 90 | put_dev_sector(sect); |
91 | return 0; | 91 | return -1; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* ++roman: sanity check: bit 0 of flg field must be set */ | 94 | /* ++roman: sanity check: bit 0 of flg field must be set */ |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 6fb4b6150d77..3d73d94d93a7 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -153,7 +153,7 @@ static struct parsed_partitions * | |||
153 | check_partition(struct gendisk *hd, struct block_device *bdev) | 153 | check_partition(struct gendisk *hd, struct block_device *bdev) |
154 | { | 154 | { |
155 | struct parsed_partitions *state; | 155 | struct parsed_partitions *state; |
156 | int i, res; | 156 | int i, res, err; |
157 | 157 | ||
158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); | 158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); |
159 | if (!state) | 159 | if (!state) |
@@ -165,19 +165,30 @@ check_partition(struct gendisk *hd, struct block_device *bdev) | |||
165 | sprintf(state->name, "p"); | 165 | sprintf(state->name, "p"); |
166 | 166 | ||
167 | state->limit = hd->minors; | 167 | state->limit = hd->minors; |
168 | i = res = 0; | 168 | i = res = err = 0; |
169 | while (!res && check_part[i]) { | 169 | while (!res && check_part[i]) { |
170 | memset(&state->parts, 0, sizeof(state->parts)); | 170 | memset(&state->parts, 0, sizeof(state->parts)); |
171 | res = check_part[i++](state, bdev); | 171 | res = check_part[i++](state, bdev); |
172 | if (res < 0) { | ||
173 | /* We have hit an I/O error which we don't report now. | ||
174 | * But record it, and let the others do their job. | ||
175 | */ | ||
176 | err = res; | ||
177 | res = 0; | ||
178 | } | ||
179 | |||
172 | } | 180 | } |
173 | if (res > 0) | 181 | if (res > 0) |
174 | return state; | 182 | return state; |
183 | if (!err) | ||
184 | /* The partition is unrecognized. So report I/O errors if there were any */ | ||
185 | res = err; | ||
175 | if (!res) | 186 | if (!res) |
176 | printk(" unknown partition table\n"); | 187 | printk(" unknown partition table\n"); |
177 | else if (warn_no_part) | 188 | else if (warn_no_part) |
178 | printk(" unable to read partition table\n"); | 189 | printk(" unable to read partition table\n"); |
179 | kfree(state); | 190 | kfree(state); |
180 | return NULL; | 191 | return ERR_PTR(res); |
181 | } | 192 | } |
182 | 193 | ||
183 | /* | 194 | /* |
@@ -265,12 +276,39 @@ static struct part_attribute part_attr_stat = { | |||
265 | .show = part_stat_read | 276 | .show = part_stat_read |
266 | }; | 277 | }; |
267 | 278 | ||
279 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
280 | |||
281 | static ssize_t part_fail_store(struct hd_struct * p, | ||
282 | const char *buf, size_t count) | ||
283 | { | ||
284 | int i; | ||
285 | |||
286 | if (count > 0 && sscanf(buf, "%d", &i) > 0) | ||
287 | p->make_it_fail = (i == 0) ? 0 : 1; | ||
288 | |||
289 | return count; | ||
290 | } | ||
291 | static ssize_t part_fail_read(struct hd_struct * p, char *page) | ||
292 | { | ||
293 | return sprintf(page, "%d\n", p->make_it_fail); | ||
294 | } | ||
295 | static struct part_attribute part_attr_fail = { | ||
296 | .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, | ||
297 | .store = part_fail_store, | ||
298 | .show = part_fail_read | ||
299 | }; | ||
300 | |||
301 | #endif | ||
302 | |||
268 | static struct attribute * default_attrs[] = { | 303 | static struct attribute * default_attrs[] = { |
269 | &part_attr_uevent.attr, | 304 | &part_attr_uevent.attr, |
270 | &part_attr_dev.attr, | 305 | &part_attr_dev.attr, |
271 | &part_attr_start.attr, | 306 | &part_attr_start.attr, |
272 | &part_attr_size.attr, | 307 | &part_attr_size.attr, |
273 | &part_attr_stat.attr, | 308 | &part_attr_stat.attr, |
309 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
310 | &part_attr_fail.attr, | ||
311 | #endif | ||
274 | NULL, | 312 | NULL, |
275 | }; | 313 | }; |
276 | 314 | ||
@@ -494,6 +532,8 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | |||
494 | disk->fops->revalidate_disk(disk); | 532 | disk->fops->revalidate_disk(disk); |
495 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 533 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
496 | return 0; | 534 | return 0; |
535 | if (IS_ERR(state)) /* I/O error reading the partition table */ | ||
536 | return PTR_ERR(state); | ||
497 | for (p = 1; p < state->limit; p++) { | 537 | for (p = 1; p < state->limit; p++) { |
498 | sector_t size = state->parts[p].size; | 538 | sector_t size = state->parts[p].size; |
499 | sector_t from = state->parts[p].from; | 539 | sector_t from = state->parts[p].from; |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index d352a7381fed..9f7ad4244f63 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -43,7 +43,7 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { | |||
43 | int | 43 | int |
44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) |
45 | { | 45 | { |
46 | int blocksize, offset, size; | 46 | int blocksize, offset, size,res; |
47 | loff_t i_size; | 47 | loff_t i_size; |
48 | dasd_information_t *info; | 48 | dasd_information_t *info; |
49 | struct hd_geometry *geo; | 49 | struct hd_geometry *geo; |
@@ -56,15 +56,16 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
56 | unsigned char *data; | 56 | unsigned char *data; |
57 | Sector sect; | 57 | Sector sect; |
58 | 58 | ||
59 | res = 0; | ||
59 | blocksize = bdev_hardsect_size(bdev); | 60 | blocksize = bdev_hardsect_size(bdev); |
60 | if (blocksize <= 0) | 61 | if (blocksize <= 0) |
61 | return 0; | 62 | goto out_exit; |
62 | i_size = i_size_read(bdev->bd_inode); | 63 | i_size = i_size_read(bdev->bd_inode); |
63 | if (i_size == 0) | 64 | if (i_size == 0) |
64 | return 0; | 65 | goto out_exit; |
65 | 66 | ||
66 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) | 67 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) |
67 | goto out_noinfo; | 68 | goto out_exit; |
68 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) | 69 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) |
69 | goto out_nogeo; | 70 | goto out_nogeo; |
70 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) | 71 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) |
@@ -72,7 +73,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
72 | 73 | ||
73 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || | 74 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || |
74 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) | 75 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
75 | goto out_noioctl; | 76 | goto out_freeall; |
76 | 77 | ||
77 | /* | 78 | /* |
78 | * Get volume label, extract name and type. | 79 | * Get volume label, extract name and type. |
@@ -92,6 +93,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
92 | EBCASC(type, 4); | 93 | EBCASC(type, 4); |
93 | EBCASC(name, 6); | 94 | EBCASC(name, 6); |
94 | 95 | ||
96 | res = 1; | ||
97 | |||
95 | /* | 98 | /* |
96 | * Three different types: CMS1, VOL1 and LNX1/unlabeled | 99 | * Three different types: CMS1, VOL1 and LNX1/unlabeled |
97 | */ | 100 | */ |
@@ -156,6 +159,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
156 | counter++; | 159 | counter++; |
157 | blk++; | 160 | blk++; |
158 | } | 161 | } |
162 | if (!data) | ||
163 | /* Are we not supposed to report this ? */ | ||
164 | goto out_readerr; | ||
159 | } else { | 165 | } else { |
160 | /* | 166 | /* |
161 | * Old style LNX1 or unlabeled disk | 167 | * Old style LNX1 or unlabeled disk |
@@ -171,18 +177,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
171 | } | 177 | } |
172 | 178 | ||
173 | printk("\n"); | 179 | printk("\n"); |
174 | kfree(label); | 180 | goto out_freeall; |
175 | kfree(geo); | 181 | |
176 | kfree(info); | ||
177 | return 1; | ||
178 | 182 | ||
179 | out_readerr: | 183 | out_readerr: |
180 | out_noioctl: | 184 | res = -1; |
185 | out_freeall: | ||
181 | kfree(label); | 186 | kfree(label); |
182 | out_nolab: | 187 | out_nolab: |
183 | kfree(geo); | 188 | kfree(geo); |
184 | out_nogeo: | 189 | out_nogeo: |
185 | kfree(info); | 190 | kfree(info); |
186 | out_noinfo: | 191 | out_exit: |
187 | return 0; | 192 | return res; |
188 | } | 193 | } |
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index c0871002d00d..d4a0fad3563b 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
@@ -74,6 +74,8 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
74 | be32_to_cpu(part->start_block) * (secsize/512), | 74 | be32_to_cpu(part->start_block) * (secsize/512), |
75 | be32_to_cpu(part->block_count) * (secsize/512)); | 75 | be32_to_cpu(part->block_count) * (secsize/512)); |
76 | 76 | ||
77 | if (!strnicmp(part->type, "Linux_RAID", 10)) | ||
78 | state->parts[slot].flags = 1; | ||
77 | #ifdef CONFIG_PPC_PMAC | 79 | #ifdef CONFIG_PPC_PMAC |
78 | /* | 80 | /* |
79 | * If this is the first bootable partition, tell the | 81 | * If this is the first bootable partition, tell the |
@@ -207,7 +207,7 @@ int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static struct pipe_buf_operations anon_pipe_buf_ops = { | 210 | static const struct pipe_buf_operations anon_pipe_buf_ops = { |
211 | .can_merge = 1, | 211 | .can_merge = 1, |
212 | .map = generic_pipe_buf_map, | 212 | .map = generic_pipe_buf_map, |
213 | .unmap = generic_pipe_buf_unmap, | 213 | .unmap = generic_pipe_buf_unmap, |
@@ -222,7 +222,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
222 | unsigned long nr_segs, loff_t pos) | 222 | unsigned long nr_segs, loff_t pos) |
223 | { | 223 | { |
224 | struct file *filp = iocb->ki_filp; | 224 | struct file *filp = iocb->ki_filp; |
225 | struct inode *inode = filp->f_dentry->d_inode; | 225 | struct inode *inode = filp->f_path.dentry->d_inode; |
226 | struct pipe_inode_info *pipe; | 226 | struct pipe_inode_info *pipe; |
227 | int do_wakeup; | 227 | int do_wakeup; |
228 | ssize_t ret; | 228 | ssize_t ret; |
@@ -243,7 +243,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
243 | if (bufs) { | 243 | if (bufs) { |
244 | int curbuf = pipe->curbuf; | 244 | int curbuf = pipe->curbuf; |
245 | struct pipe_buffer *buf = pipe->bufs + curbuf; | 245 | struct pipe_buffer *buf = pipe->bufs + curbuf; |
246 | struct pipe_buf_operations *ops = buf->ops; | 246 | const struct pipe_buf_operations *ops = buf->ops; |
247 | void *addr; | 247 | void *addr; |
248 | size_t chars = buf->len; | 248 | size_t chars = buf->len; |
249 | int error, atomic; | 249 | int error, atomic; |
@@ -335,7 +335,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, | |||
335 | unsigned long nr_segs, loff_t ppos) | 335 | unsigned long nr_segs, loff_t ppos) |
336 | { | 336 | { |
337 | struct file *filp = iocb->ki_filp; | 337 | struct file *filp = iocb->ki_filp; |
338 | struct inode *inode = filp->f_dentry->d_inode; | 338 | struct inode *inode = filp->f_path.dentry->d_inode; |
339 | struct pipe_inode_info *pipe; | 339 | struct pipe_inode_info *pipe; |
340 | ssize_t ret; | 340 | ssize_t ret; |
341 | int do_wakeup; | 341 | int do_wakeup; |
@@ -365,7 +365,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, | |||
365 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & | 365 | int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & |
366 | (PIPE_BUFFERS-1); | 366 | (PIPE_BUFFERS-1); |
367 | struct pipe_buffer *buf = pipe->bufs + lastbuf; | 367 | struct pipe_buffer *buf = pipe->bufs + lastbuf; |
368 | struct pipe_buf_operations *ops = buf->ops; | 368 | const struct pipe_buf_operations *ops = buf->ops; |
369 | int offset = buf->offset + buf->len; | 369 | int offset = buf->offset + buf->len; |
370 | 370 | ||
371 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { | 371 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
@@ -520,7 +520,7 @@ static int | |||
520 | pipe_ioctl(struct inode *pino, struct file *filp, | 520 | pipe_ioctl(struct inode *pino, struct file *filp, |
521 | unsigned int cmd, unsigned long arg) | 521 | unsigned int cmd, unsigned long arg) |
522 | { | 522 | { |
523 | struct inode *inode = filp->f_dentry->d_inode; | 523 | struct inode *inode = filp->f_path.dentry->d_inode; |
524 | struct pipe_inode_info *pipe; | 524 | struct pipe_inode_info *pipe; |
525 | int count, buf, nrbufs; | 525 | int count, buf, nrbufs; |
526 | 526 | ||
@@ -548,7 +548,7 @@ static unsigned int | |||
548 | pipe_poll(struct file *filp, poll_table *wait) | 548 | pipe_poll(struct file *filp, poll_table *wait) |
549 | { | 549 | { |
550 | unsigned int mask; | 550 | unsigned int mask; |
551 | struct inode *inode = filp->f_dentry->d_inode; | 551 | struct inode *inode = filp->f_path.dentry->d_inode; |
552 | struct pipe_inode_info *pipe = inode->i_pipe; | 552 | struct pipe_inode_info *pipe = inode->i_pipe; |
553 | int nrbufs; | 553 | int nrbufs; |
554 | 554 | ||
@@ -601,7 +601,7 @@ pipe_release(struct inode *inode, int decr, int decw) | |||
601 | static int | 601 | static int |
602 | pipe_read_fasync(int fd, struct file *filp, int on) | 602 | pipe_read_fasync(int fd, struct file *filp, int on) |
603 | { | 603 | { |
604 | struct inode *inode = filp->f_dentry->d_inode; | 604 | struct inode *inode = filp->f_path.dentry->d_inode; |
605 | int retval; | 605 | int retval; |
606 | 606 | ||
607 | mutex_lock(&inode->i_mutex); | 607 | mutex_lock(&inode->i_mutex); |
@@ -618,7 +618,7 @@ pipe_read_fasync(int fd, struct file *filp, int on) | |||
618 | static int | 618 | static int |
619 | pipe_write_fasync(int fd, struct file *filp, int on) | 619 | pipe_write_fasync(int fd, struct file *filp, int on) |
620 | { | 620 | { |
621 | struct inode *inode = filp->f_dentry->d_inode; | 621 | struct inode *inode = filp->f_path.dentry->d_inode; |
622 | int retval; | 622 | int retval; |
623 | 623 | ||
624 | mutex_lock(&inode->i_mutex); | 624 | mutex_lock(&inode->i_mutex); |
@@ -635,7 +635,7 @@ pipe_write_fasync(int fd, struct file *filp, int on) | |||
635 | static int | 635 | static int |
636 | pipe_rdwr_fasync(int fd, struct file *filp, int on) | 636 | pipe_rdwr_fasync(int fd, struct file *filp, int on) |
637 | { | 637 | { |
638 | struct inode *inode = filp->f_dentry->d_inode; | 638 | struct inode *inode = filp->f_path.dentry->d_inode; |
639 | struct pipe_inode_info *pipe = inode->i_pipe; | 639 | struct pipe_inode_info *pipe = inode->i_pipe; |
640 | int retval; | 640 | int retval; |
641 | 641 | ||
@@ -756,7 +756,7 @@ const struct file_operations rdwr_fifo_fops = { | |||
756 | .fasync = pipe_rdwr_fasync, | 756 | .fasync = pipe_rdwr_fasync, |
757 | }; | 757 | }; |
758 | 758 | ||
759 | static struct file_operations read_pipe_fops = { | 759 | static const struct file_operations read_pipe_fops = { |
760 | .llseek = no_llseek, | 760 | .llseek = no_llseek, |
761 | .read = do_sync_read, | 761 | .read = do_sync_read, |
762 | .aio_read = pipe_read, | 762 | .aio_read = pipe_read, |
@@ -768,7 +768,7 @@ static struct file_operations read_pipe_fops = { | |||
768 | .fasync = pipe_read_fasync, | 768 | .fasync = pipe_read_fasync, |
769 | }; | 769 | }; |
770 | 770 | ||
771 | static struct file_operations write_pipe_fops = { | 771 | static const struct file_operations write_pipe_fops = { |
772 | .llseek = no_llseek, | 772 | .llseek = no_llseek, |
773 | .read = bad_pipe_r, | 773 | .read = bad_pipe_r, |
774 | .write = do_sync_write, | 774 | .write = do_sync_write, |
@@ -780,7 +780,7 @@ static struct file_operations write_pipe_fops = { | |||
780 | .fasync = pipe_write_fasync, | 780 | .fasync = pipe_write_fasync, |
781 | }; | 781 | }; |
782 | 782 | ||
783 | static struct file_operations rdwr_pipe_fops = { | 783 | static const struct file_operations rdwr_pipe_fops = { |
784 | .llseek = no_llseek, | 784 | .llseek = no_llseek, |
785 | .read = do_sync_read, | 785 | .read = do_sync_read, |
786 | .aio_read = pipe_read, | 786 | .aio_read = pipe_read, |
@@ -830,7 +830,14 @@ void free_pipe_info(struct inode *inode) | |||
830 | static struct vfsmount *pipe_mnt __read_mostly; | 830 | static struct vfsmount *pipe_mnt __read_mostly; |
831 | static int pipefs_delete_dentry(struct dentry *dentry) | 831 | static int pipefs_delete_dentry(struct dentry *dentry) |
832 | { | 832 | { |
833 | return 1; | 833 | /* |
834 | * At creation time, we pretended this dentry was hashed | ||
835 | * (by clearing DCACHE_UNHASHED bit in d_flags) | ||
836 | * At delete time, we restore the truth : not hashed. | ||
837 | * (so that dput() can proceed correctly) | ||
838 | */ | ||
839 | dentry->d_flags |= DCACHE_UNHASHED; | ||
840 | return 0; | ||
834 | } | 841 | } |
835 | 842 | ||
836 | static struct dentry_operations pipefs_dentry_operations = { | 843 | static struct dentry_operations pipefs_dentry_operations = { |
@@ -891,19 +898,24 @@ struct file *create_write_pipe(void) | |||
891 | if (!inode) | 898 | if (!inode) |
892 | goto err_file; | 899 | goto err_file; |
893 | 900 | ||
894 | sprintf(name, "[%lu]", inode->i_ino); | 901 | this.len = sprintf(name, "[%lu]", inode->i_ino); |
895 | this.name = name; | 902 | this.name = name; |
896 | this.len = strlen(name); | 903 | this.hash = 0; |
897 | this.hash = inode->i_ino; /* will go */ | ||
898 | err = -ENOMEM; | 904 | err = -ENOMEM; |
899 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 905 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
900 | if (!dentry) | 906 | if (!dentry) |
901 | goto err_inode; | 907 | goto err_inode; |
902 | 908 | ||
903 | dentry->d_op = &pipefs_dentry_operations; | 909 | dentry->d_op = &pipefs_dentry_operations; |
904 | d_add(dentry, inode); | 910 | /* |
905 | f->f_vfsmnt = mntget(pipe_mnt); | 911 | * We dont want to publish this dentry into global dentry hash table. |
906 | f->f_dentry = dentry; | 912 | * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED |
913 | * This permits a working /proc/$pid/fd/XXX on pipes | ||
914 | */ | ||
915 | dentry->d_flags &= ~DCACHE_UNHASHED; | ||
916 | d_instantiate(dentry, inode); | ||
917 | f->f_path.mnt = mntget(pipe_mnt); | ||
918 | f->f_path.dentry = dentry; | ||
907 | f->f_mapping = inode->i_mapping; | 919 | f->f_mapping = inode->i_mapping; |
908 | 920 | ||
909 | f->f_flags = O_WRONLY; | 921 | f->f_flags = O_WRONLY; |
@@ -923,8 +935,9 @@ struct file *create_write_pipe(void) | |||
923 | 935 | ||
924 | void free_write_pipe(struct file *f) | 936 | void free_write_pipe(struct file *f) |
925 | { | 937 | { |
926 | mntput(f->f_vfsmnt); | 938 | free_pipe_info(f->f_dentry->d_inode); |
927 | dput(f->f_dentry); | 939 | dput(f->f_path.dentry); |
940 | mntput(f->f_path.mnt); | ||
928 | put_filp(f); | 941 | put_filp(f); |
929 | } | 942 | } |
930 | 943 | ||
@@ -935,9 +948,9 @@ struct file *create_read_pipe(struct file *wrf) | |||
935 | return ERR_PTR(-ENFILE); | 948 | return ERR_PTR(-ENFILE); |
936 | 949 | ||
937 | /* Grab pipe from the writer */ | 950 | /* Grab pipe from the writer */ |
938 | f->f_vfsmnt = mntget(wrf->f_vfsmnt); | 951 | f->f_path.mnt = mntget(wrf->f_path.mnt); |
939 | f->f_dentry = dget(wrf->f_dentry); | 952 | f->f_path.dentry = dget(wrf->f_path.dentry); |
940 | f->f_mapping = wrf->f_dentry->d_inode->i_mapping; | 953 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; |
941 | 954 | ||
942 | f->f_pos = 0; | 955 | f->f_pos = 0; |
943 | f->f_flags = O_RDONLY; | 956 | f->f_flags = O_RDONLY; |
@@ -982,6 +995,8 @@ int do_pipe(int *fd) | |||
982 | err_fdr: | 995 | err_fdr: |
983 | put_unused_fd(fdr); | 996 | put_unused_fd(fdr); |
984 | err_read_pipe: | 997 | err_read_pipe: |
998 | dput(fr->f_dentry); | ||
999 | mntput(fr->f_vfsmnt); | ||
985 | put_filp(fr); | 1000 | put_filp(fr); |
986 | err_write_pipe: | 1001 | err_write_pipe: |
987 | free_write_pipe(fw); | 1002 | free_write_pipe(fw); |
diff --git a/fs/pnode.c b/fs/pnode.c index da42ee61c1df..56aacead8362 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Author : Ram Pai (linuxram@us.ibm.com) | 6 | * Author : Ram Pai (linuxram@us.ibm.com) |
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | #include <linux/namespace.h> | 9 | #include <linux/mnt_namespace.h> |
10 | #include <linux/mount.h> | 10 | #include <linux/mount.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include "pnode.h" | 12 | #include "pnode.h" |
diff --git a/fs/pnode.h b/fs/pnode.h index 020e1bb60fdb..d45bd8ec36bf 100644 --- a/fs/pnode.h +++ b/fs/pnode.h | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) | 14 | #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) |
15 | #define IS_MNT_SLAVE(mnt) (mnt->mnt_master) | 15 | #define IS_MNT_SLAVE(mnt) (mnt->mnt_master) |
16 | #define IS_MNT_NEW(mnt) (!mnt->mnt_namespace) | 16 | #define IS_MNT_NEW(mnt) (!mnt->mnt_ns) |
17 | #define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED) | 17 | #define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED) |
18 | #define IS_MNT_UNBINDABLE(mnt) (mnt->mnt_flags & MNT_UNBINDABLE) | 18 | #define IS_MNT_UNBINDABLE(mnt) (mnt->mnt_flags & MNT_UNBINDABLE) |
19 | 19 | ||
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 7431d7ba2d09..f6c776272572 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o | |||
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | kmsg.o proc_tty.o proc_misc.o | 11 | proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 13 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
16 | proc-$(CONFIG_PRINTK) += kmsg.o | ||
diff --git a/fs/proc/array.c b/fs/proc/array.c index 25e917fb4739..70e4fab117b1 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -346,20 +346,13 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
346 | sigemptyset(&sigcatch); | 346 | sigemptyset(&sigcatch); |
347 | cutime = cstime = utime = stime = cputime_zero; | 347 | cutime = cstime = utime = stime = cputime_zero; |
348 | 348 | ||
349 | mutex_lock(&tty_mutex); | ||
350 | rcu_read_lock(); | 349 | rcu_read_lock(); |
351 | if (lock_task_sighand(task, &flags)) { | 350 | if (lock_task_sighand(task, &flags)) { |
352 | struct signal_struct *sig = task->signal; | 351 | struct signal_struct *sig = task->signal; |
353 | struct tty_struct *tty = sig->tty; | 352 | |
354 | 353 | if (sig->tty) { | |
355 | if (tty) { | 354 | tty_pgrp = sig->tty->pgrp; |
356 | /* | 355 | tty_nr = new_encode_dev(tty_devnum(sig->tty)); |
357 | * sig->tty is not stable, but tty_mutex | ||
358 | * protects us from release_dev(tty) | ||
359 | */ | ||
360 | barrier(); | ||
361 | tty_pgrp = tty->pgrp; | ||
362 | tty_nr = new_encode_dev(tty_devnum(tty)); | ||
363 | } | 356 | } |
364 | 357 | ||
365 | num_threads = atomic_read(&sig->count); | 358 | num_threads = atomic_read(&sig->count); |
@@ -388,14 +381,13 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
388 | stime = cputime_add(stime, sig->stime); | 381 | stime = cputime_add(stime, sig->stime); |
389 | } | 382 | } |
390 | 383 | ||
391 | sid = sig->session; | 384 | sid = signal_session(sig); |
392 | pgid = process_group(task); | 385 | pgid = process_group(task); |
393 | ppid = rcu_dereference(task->real_parent)->tgid; | 386 | ppid = rcu_dereference(task->real_parent)->tgid; |
394 | 387 | ||
395 | unlock_task_sighand(task, &flags); | 388 | unlock_task_sighand(task, &flags); |
396 | } | 389 | } |
397 | rcu_read_unlock(); | 390 | rcu_read_unlock(); |
398 | mutex_unlock(&tty_mutex); | ||
399 | 391 | ||
400 | if (!whole || num_threads<2) | 392 | if (!whole || num_threads<2) |
401 | wchan = get_wchan(task); | 393 | wchan = get_wchan(task); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 795319c54f72..77a57b5799c4 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -59,7 +59,7 @@ | |||
59 | #include <linux/string.h> | 59 | #include <linux/string.h> |
60 | #include <linux/seq_file.h> | 60 | #include <linux/seq_file.h> |
61 | #include <linux/namei.h> | 61 | #include <linux/namei.h> |
62 | #include <linux/namespace.h> | 62 | #include <linux/mnt_namespace.h> |
63 | #include <linux/mm.h> | 63 | #include <linux/mm.h> |
64 | #include <linux/smp_lock.h> | 64 | #include <linux/smp_lock.h> |
65 | #include <linux/rcupdate.h> | 65 | #include <linux/rcupdate.h> |
@@ -365,33 +365,33 @@ struct proc_mounts { | |||
365 | static int mounts_open(struct inode *inode, struct file *file) | 365 | static int mounts_open(struct inode *inode, struct file *file) |
366 | { | 366 | { |
367 | struct task_struct *task = get_proc_task(inode); | 367 | struct task_struct *task = get_proc_task(inode); |
368 | struct namespace *namespace = NULL; | 368 | struct mnt_namespace *ns = NULL; |
369 | struct proc_mounts *p; | 369 | struct proc_mounts *p; |
370 | int ret = -EINVAL; | 370 | int ret = -EINVAL; |
371 | 371 | ||
372 | if (task) { | 372 | if (task) { |
373 | task_lock(task); | 373 | task_lock(task); |
374 | namespace = task->nsproxy->namespace; | 374 | ns = task->nsproxy->mnt_ns; |
375 | if (namespace) | 375 | if (ns) |
376 | get_namespace(namespace); | 376 | get_mnt_ns(ns); |
377 | task_unlock(task); | 377 | task_unlock(task); |
378 | put_task_struct(task); | 378 | put_task_struct(task); |
379 | } | 379 | } |
380 | 380 | ||
381 | if (namespace) { | 381 | if (ns) { |
382 | ret = -ENOMEM; | 382 | ret = -ENOMEM; |
383 | p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); | 383 | p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); |
384 | if (p) { | 384 | if (p) { |
385 | file->private_data = &p->m; | 385 | file->private_data = &p->m; |
386 | ret = seq_open(file, &mounts_op); | 386 | ret = seq_open(file, &mounts_op); |
387 | if (!ret) { | 387 | if (!ret) { |
388 | p->m.private = namespace; | 388 | p->m.private = ns; |
389 | p->event = namespace->event; | 389 | p->event = ns->event; |
390 | return 0; | 390 | return 0; |
391 | } | 391 | } |
392 | kfree(p); | 392 | kfree(p); |
393 | } | 393 | } |
394 | put_namespace(namespace); | 394 | put_mnt_ns(ns); |
395 | } | 395 | } |
396 | return ret; | 396 | return ret; |
397 | } | 397 | } |
@@ -399,15 +399,15 @@ static int mounts_open(struct inode *inode, struct file *file) | |||
399 | static int mounts_release(struct inode *inode, struct file *file) | 399 | static int mounts_release(struct inode *inode, struct file *file) |
400 | { | 400 | { |
401 | struct seq_file *m = file->private_data; | 401 | struct seq_file *m = file->private_data; |
402 | struct namespace *namespace = m->private; | 402 | struct mnt_namespace *ns = m->private; |
403 | put_namespace(namespace); | 403 | put_mnt_ns(ns); |
404 | return seq_release(inode, file); | 404 | return seq_release(inode, file); |
405 | } | 405 | } |
406 | 406 | ||
407 | static unsigned mounts_poll(struct file *file, poll_table *wait) | 407 | static unsigned mounts_poll(struct file *file, poll_table *wait) |
408 | { | 408 | { |
409 | struct proc_mounts *p = file->private_data; | 409 | struct proc_mounts *p = file->private_data; |
410 | struct namespace *ns = p->m.private; | 410 | struct mnt_namespace *ns = p->m.private; |
411 | unsigned res = 0; | 411 | unsigned res = 0; |
412 | 412 | ||
413 | poll_wait(file, &ns->poll, wait); | 413 | poll_wait(file, &ns->poll, wait); |
@@ -437,21 +437,21 @@ static int mountstats_open(struct inode *inode, struct file *file) | |||
437 | 437 | ||
438 | if (!ret) { | 438 | if (!ret) { |
439 | struct seq_file *m = file->private_data; | 439 | struct seq_file *m = file->private_data; |
440 | struct namespace *namespace = NULL; | 440 | struct mnt_namespace *mnt_ns = NULL; |
441 | struct task_struct *task = get_proc_task(inode); | 441 | struct task_struct *task = get_proc_task(inode); |
442 | 442 | ||
443 | if (task) { | 443 | if (task) { |
444 | task_lock(task); | 444 | task_lock(task); |
445 | if (task->nsproxy) | 445 | if (task->nsproxy) |
446 | namespace = task->nsproxy->namespace; | 446 | mnt_ns = task->nsproxy->mnt_ns; |
447 | if (namespace) | 447 | if (mnt_ns) |
448 | get_namespace(namespace); | 448 | get_mnt_ns(mnt_ns); |
449 | task_unlock(task); | 449 | task_unlock(task); |
450 | put_task_struct(task); | 450 | put_task_struct(task); |
451 | } | 451 | } |
452 | 452 | ||
453 | if (namespace) | 453 | if (mnt_ns) |
454 | m->private = namespace; | 454 | m->private = mnt_ns; |
455 | else { | 455 | else { |
456 | seq_release(inode, file); | 456 | seq_release(inode, file); |
457 | ret = -EINVAL; | 457 | ret = -EINVAL; |
@@ -472,7 +472,7 @@ static struct file_operations proc_mountstats_operations = { | |||
472 | static ssize_t proc_info_read(struct file * file, char __user * buf, | 472 | static ssize_t proc_info_read(struct file * file, char __user * buf, |
473 | size_t count, loff_t *ppos) | 473 | size_t count, loff_t *ppos) |
474 | { | 474 | { |
475 | struct inode * inode = file->f_dentry->d_inode; | 475 | struct inode * inode = file->f_path.dentry->d_inode; |
476 | unsigned long page; | 476 | unsigned long page; |
477 | ssize_t length; | 477 | ssize_t length; |
478 | struct task_struct *task = get_proc_task(inode); | 478 | struct task_struct *task = get_proc_task(inode); |
@@ -512,7 +512,7 @@ static int mem_open(struct inode* inode, struct file* file) | |||
512 | static ssize_t mem_read(struct file * file, char __user * buf, | 512 | static ssize_t mem_read(struct file * file, char __user * buf, |
513 | size_t count, loff_t *ppos) | 513 | size_t count, loff_t *ppos) |
514 | { | 514 | { |
515 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | 515 | struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); |
516 | char *page; | 516 | char *page; |
517 | unsigned long src = *ppos; | 517 | unsigned long src = *ppos; |
518 | int ret = -ESRCH; | 518 | int ret = -ESRCH; |
@@ -584,7 +584,7 @@ static ssize_t mem_write(struct file * file, const char * buf, | |||
584 | { | 584 | { |
585 | int copied; | 585 | int copied; |
586 | char *page; | 586 | char *page; |
587 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | 587 | struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); |
588 | unsigned long dst = *ppos; | 588 | unsigned long dst = *ppos; |
589 | 589 | ||
590 | copied = -ESRCH; | 590 | copied = -ESRCH; |
@@ -654,7 +654,7 @@ static struct file_operations proc_mem_operations = { | |||
654 | static ssize_t oom_adjust_read(struct file *file, char __user *buf, | 654 | static ssize_t oom_adjust_read(struct file *file, char __user *buf, |
655 | size_t count, loff_t *ppos) | 655 | size_t count, loff_t *ppos) |
656 | { | 656 | { |
657 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | 657 | struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); |
658 | char buffer[PROC_NUMBUF]; | 658 | char buffer[PROC_NUMBUF]; |
659 | size_t len; | 659 | size_t len; |
660 | int oom_adjust; | 660 | int oom_adjust; |
@@ -683,8 +683,6 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
683 | char buffer[PROC_NUMBUF], *end; | 683 | char buffer[PROC_NUMBUF], *end; |
684 | int oom_adjust; | 684 | int oom_adjust; |
685 | 685 | ||
686 | if (!capable(CAP_SYS_RESOURCE)) | ||
687 | return -EPERM; | ||
688 | memset(buffer, 0, sizeof(buffer)); | 686 | memset(buffer, 0, sizeof(buffer)); |
689 | if (count > sizeof(buffer) - 1) | 687 | if (count > sizeof(buffer) - 1) |
690 | count = sizeof(buffer) - 1; | 688 | count = sizeof(buffer) - 1; |
@@ -696,9 +694,13 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
696 | return -EINVAL; | 694 | return -EINVAL; |
697 | if (*end == '\n') | 695 | if (*end == '\n') |
698 | end++; | 696 | end++; |
699 | task = get_proc_task(file->f_dentry->d_inode); | 697 | task = get_proc_task(file->f_path.dentry->d_inode); |
700 | if (!task) | 698 | if (!task) |
701 | return -ESRCH; | 699 | return -ESRCH; |
700 | if (oom_adjust < task->oomkilladj && !capable(CAP_SYS_RESOURCE)) { | ||
701 | put_task_struct(task); | ||
702 | return -EACCES; | ||
703 | } | ||
702 | task->oomkilladj = oom_adjust; | 704 | task->oomkilladj = oom_adjust; |
703 | put_task_struct(task); | 705 | put_task_struct(task); |
704 | if (end - buffer == 0) | 706 | if (end - buffer == 0) |
@@ -716,7 +718,7 @@ static struct file_operations proc_oom_adjust_operations = { | |||
716 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | 718 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, |
717 | size_t count, loff_t *ppos) | 719 | size_t count, loff_t *ppos) |
718 | { | 720 | { |
719 | struct inode * inode = file->f_dentry->d_inode; | 721 | struct inode * inode = file->f_path.dentry->d_inode; |
720 | struct task_struct *task = get_proc_task(inode); | 722 | struct task_struct *task = get_proc_task(inode); |
721 | ssize_t length; | 723 | ssize_t length; |
722 | char tmpbuf[TMPBUFLEN]; | 724 | char tmpbuf[TMPBUFLEN]; |
@@ -732,7 +734,7 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | |||
732 | static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, | 734 | static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, |
733 | size_t count, loff_t *ppos) | 735 | size_t count, loff_t *ppos) |
734 | { | 736 | { |
735 | struct inode * inode = file->f_dentry->d_inode; | 737 | struct inode * inode = file->f_path.dentry->d_inode; |
736 | char *page, *tmp; | 738 | char *page, *tmp; |
737 | ssize_t length; | 739 | ssize_t length; |
738 | uid_t loginuid; | 740 | uid_t loginuid; |
@@ -851,6 +853,65 @@ static struct file_operations proc_seccomp_operations = { | |||
851 | }; | 853 | }; |
852 | #endif /* CONFIG_SECCOMP */ | 854 | #endif /* CONFIG_SECCOMP */ |
853 | 855 | ||
856 | #ifdef CONFIG_FAULT_INJECTION | ||
857 | static ssize_t proc_fault_inject_read(struct file * file, char __user * buf, | ||
858 | size_t count, loff_t *ppos) | ||
859 | { | ||
860 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | ||
861 | char buffer[PROC_NUMBUF]; | ||
862 | size_t len; | ||
863 | int make_it_fail; | ||
864 | loff_t __ppos = *ppos; | ||
865 | |||
866 | if (!task) | ||
867 | return -ESRCH; | ||
868 | make_it_fail = task->make_it_fail; | ||
869 | put_task_struct(task); | ||
870 | |||
871 | len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail); | ||
872 | if (__ppos >= len) | ||
873 | return 0; | ||
874 | if (count > len-__ppos) | ||
875 | count = len-__ppos; | ||
876 | if (copy_to_user(buf, buffer + __ppos, count)) | ||
877 | return -EFAULT; | ||
878 | *ppos = __ppos + count; | ||
879 | return count; | ||
880 | } | ||
881 | |||
882 | static ssize_t proc_fault_inject_write(struct file * file, | ||
883 | const char __user * buf, size_t count, loff_t *ppos) | ||
884 | { | ||
885 | struct task_struct *task; | ||
886 | char buffer[PROC_NUMBUF], *end; | ||
887 | int make_it_fail; | ||
888 | |||
889 | if (!capable(CAP_SYS_RESOURCE)) | ||
890 | return -EPERM; | ||
891 | memset(buffer, 0, sizeof(buffer)); | ||
892 | if (count > sizeof(buffer) - 1) | ||
893 | count = sizeof(buffer) - 1; | ||
894 | if (copy_from_user(buffer, buf, count)) | ||
895 | return -EFAULT; | ||
896 | make_it_fail = simple_strtol(buffer, &end, 0); | ||
897 | if (*end == '\n') | ||
898 | end++; | ||
899 | task = get_proc_task(file->f_dentry->d_inode); | ||
900 | if (!task) | ||
901 | return -ESRCH; | ||
902 | task->make_it_fail = make_it_fail; | ||
903 | put_task_struct(task); | ||
904 | if (end - buffer == 0) | ||
905 | return -EIO; | ||
906 | return end - buffer; | ||
907 | } | ||
908 | |||
909 | static struct file_operations proc_fault_inject_operations = { | ||
910 | .read = proc_fault_inject_read, | ||
911 | .write = proc_fault_inject_write, | ||
912 | }; | ||
913 | #endif | ||
914 | |||
854 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 915 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
855 | { | 916 | { |
856 | struct inode *inode = dentry->d_inode; | 917 | struct inode *inode = dentry->d_inode; |
@@ -1076,7 +1137,7 @@ static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | |||
1076 | char *name, int len, | 1137 | char *name, int len, |
1077 | instantiate_t instantiate, struct task_struct *task, void *ptr) | 1138 | instantiate_t instantiate, struct task_struct *task, void *ptr) |
1078 | { | 1139 | { |
1079 | struct dentry *child, *dir = filp->f_dentry; | 1140 | struct dentry *child, *dir = filp->f_path.dentry; |
1080 | struct inode *inode; | 1141 | struct inode *inode; |
1081 | struct qstr qname; | 1142 | struct qstr qname; |
1082 | ino_t ino = 0; | 1143 | ino_t ino = 0; |
@@ -1155,8 +1216,8 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm | |||
1155 | spin_lock(&files->file_lock); | 1216 | spin_lock(&files->file_lock); |
1156 | file = fcheck_files(files, fd); | 1217 | file = fcheck_files(files, fd); |
1157 | if (file) { | 1218 | if (file) { |
1158 | *mnt = mntget(file->f_vfsmnt); | 1219 | *mnt = mntget(file->f_path.mnt); |
1159 | *dentry = dget(file->f_dentry); | 1220 | *dentry = dget(file->f_path.dentry); |
1160 | spin_unlock(&files->file_lock); | 1221 | spin_unlock(&files->file_lock); |
1161 | put_files_struct(files); | 1222 | put_files_struct(files); |
1162 | return 0; | 1223 | return 0; |
@@ -1291,7 +1352,7 @@ static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir | |||
1291 | 1352 | ||
1292 | static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) | 1353 | static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) |
1293 | { | 1354 | { |
1294 | struct dentry *dentry = filp->f_dentry; | 1355 | struct dentry *dentry = filp->f_path.dentry; |
1295 | struct inode *inode = dentry->d_inode; | 1356 | struct inode *inode = dentry->d_inode; |
1296 | struct task_struct *p = get_proc_task(inode); | 1357 | struct task_struct *p = get_proc_task(inode); |
1297 | unsigned int fd, tid, ino; | 1358 | unsigned int fd, tid, ino; |
@@ -1438,7 +1499,7 @@ static int proc_pident_readdir(struct file *filp, | |||
1438 | { | 1499 | { |
1439 | int i; | 1500 | int i; |
1440 | int pid; | 1501 | int pid; |
1441 | struct dentry *dentry = filp->f_dentry; | 1502 | struct dentry *dentry = filp->f_path.dentry; |
1442 | struct inode *inode = dentry->d_inode; | 1503 | struct inode *inode = dentry->d_inode; |
1443 | struct task_struct *task = get_proc_task(inode); | 1504 | struct task_struct *task = get_proc_task(inode); |
1444 | struct pid_entry *p, *last; | 1505 | struct pid_entry *p, *last; |
@@ -1494,7 +1555,7 @@ out_no_task: | |||
1494 | static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, | 1555 | static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, |
1495 | size_t count, loff_t *ppos) | 1556 | size_t count, loff_t *ppos) |
1496 | { | 1557 | { |
1497 | struct inode * inode = file->f_dentry->d_inode; | 1558 | struct inode * inode = file->f_path.dentry->d_inode; |
1498 | unsigned long page; | 1559 | unsigned long page; |
1499 | ssize_t length; | 1560 | ssize_t length; |
1500 | struct task_struct *task = get_proc_task(inode); | 1561 | struct task_struct *task = get_proc_task(inode); |
@@ -1510,7 +1571,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, | |||
1510 | goto out; | 1571 | goto out; |
1511 | 1572 | ||
1512 | length = security_getprocattr(task, | 1573 | length = security_getprocattr(task, |
1513 | (char*)file->f_dentry->d_name.name, | 1574 | (char*)file->f_path.dentry->d_name.name, |
1514 | (void*)page, count); | 1575 | (void*)page, count); |
1515 | if (length >= 0) | 1576 | if (length >= 0) |
1516 | length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); | 1577 | length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); |
@@ -1524,7 +1585,7 @@ out_no_task: | |||
1524 | static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | 1585 | static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, |
1525 | size_t count, loff_t *ppos) | 1586 | size_t count, loff_t *ppos) |
1526 | { | 1587 | { |
1527 | struct inode * inode = file->f_dentry->d_inode; | 1588 | struct inode * inode = file->f_path.dentry->d_inode; |
1528 | char *page; | 1589 | char *page; |
1529 | ssize_t length; | 1590 | ssize_t length; |
1530 | struct task_struct *task = get_proc_task(inode); | 1591 | struct task_struct *task = get_proc_task(inode); |
@@ -1550,7 +1611,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | |||
1550 | goto out_free; | 1611 | goto out_free; |
1551 | 1612 | ||
1552 | length = security_setprocattr(task, | 1613 | length = security_setprocattr(task, |
1553 | (char*)file->f_dentry->d_name.name, | 1614 | (char*)file->f_path.dentry->d_name.name, |
1554 | (void*)page, count); | 1615 | (void*)page, count); |
1555 | out_free: | 1616 | out_free: |
1556 | free_page((unsigned long) page); | 1617 | free_page((unsigned long) page); |
@@ -1743,6 +1804,27 @@ static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filld | |||
1743 | proc_base_instantiate, task, p); | 1804 | proc_base_instantiate, task, p); |
1744 | } | 1805 | } |
1745 | 1806 | ||
1807 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
1808 | static int proc_pid_io_accounting(struct task_struct *task, char *buffer) | ||
1809 | { | ||
1810 | return sprintf(buffer, | ||
1811 | "rchar: %llu\n" | ||
1812 | "wchar: %llu\n" | ||
1813 | "syscr: %llu\n" | ||
1814 | "syscw: %llu\n" | ||
1815 | "read_bytes: %llu\n" | ||
1816 | "write_bytes: %llu\n" | ||
1817 | "cancelled_write_bytes: %llu\n", | ||
1818 | (unsigned long long)task->rchar, | ||
1819 | (unsigned long long)task->wchar, | ||
1820 | (unsigned long long)task->syscr, | ||
1821 | (unsigned long long)task->syscw, | ||
1822 | (unsigned long long)task->ioac.read_bytes, | ||
1823 | (unsigned long long)task->ioac.write_bytes, | ||
1824 | (unsigned long long)task->ioac.cancelled_write_bytes); | ||
1825 | } | ||
1826 | #endif | ||
1827 | |||
1746 | /* | 1828 | /* |
1747 | * Thread groups | 1829 | * Thread groups |
1748 | */ | 1830 | */ |
@@ -1791,6 +1873,12 @@ static struct pid_entry tgid_base_stuff[] = { | |||
1791 | #ifdef CONFIG_AUDITSYSCALL | 1873 | #ifdef CONFIG_AUDITSYSCALL |
1792 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 1874 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
1793 | #endif | 1875 | #endif |
1876 | #ifdef CONFIG_FAULT_INJECTION | ||
1877 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | ||
1878 | #endif | ||
1879 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
1880 | INF("io", S_IRUGO, pid_io_accounting), | ||
1881 | #endif | ||
1794 | }; | 1882 | }; |
1795 | 1883 | ||
1796 | static int proc_tgid_base_readdir(struct file * filp, | 1884 | static int proc_tgid_base_readdir(struct file * filp, |
@@ -1883,8 +1971,9 @@ out: | |||
1883 | return; | 1971 | return; |
1884 | } | 1972 | } |
1885 | 1973 | ||
1886 | struct dentry *proc_pid_instantiate(struct inode *dir, | 1974 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
1887 | struct dentry * dentry, struct task_struct *task, void *ptr) | 1975 | struct dentry * dentry, |
1976 | struct task_struct *task, void *ptr) | ||
1888 | { | 1977 | { |
1889 | struct dentry *error = ERR_PTR(-ENOENT); | 1978 | struct dentry *error = ERR_PTR(-ENOENT); |
1890 | struct inode *inode; | 1979 | struct inode *inode; |
@@ -1991,7 +2080,7 @@ static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldi | |||
1991 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | 2080 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) |
1992 | { | 2081 | { |
1993 | unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; | 2082 | unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; |
1994 | struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode); | 2083 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
1995 | struct task_struct *task; | 2084 | struct task_struct *task; |
1996 | int tgid; | 2085 | int tgid; |
1997 | 2086 | ||
@@ -2065,6 +2154,9 @@ static struct pid_entry tid_base_stuff[] = { | |||
2065 | #ifdef CONFIG_AUDITSYSCALL | 2154 | #ifdef CONFIG_AUDITSYSCALL |
2066 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2155 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
2067 | #endif | 2156 | #endif |
2157 | #ifdef CONFIG_FAULT_INJECTION | ||
2158 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | ||
2159 | #endif | ||
2068 | }; | 2160 | }; |
2069 | 2161 | ||
2070 | static int proc_tid_base_readdir(struct file * filp, | 2162 | static int proc_tid_base_readdir(struct file * filp, |
@@ -2232,7 +2324,7 @@ static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filld | |||
2232 | /* for the /proc/TGID/task/ directories */ | 2324 | /* for the /proc/TGID/task/ directories */ |
2233 | static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir) | 2325 | static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir) |
2234 | { | 2326 | { |
2235 | struct dentry *dentry = filp->f_dentry; | 2327 | struct dentry *dentry = filp->f_path.dentry; |
2236 | struct inode *inode = dentry->d_inode; | 2328 | struct inode *inode = dentry->d_inode; |
2237 | struct task_struct *leader = get_proc_task(inode); | 2329 | struct task_struct *leader = get_proc_task(inode); |
2238 | struct task_struct *task; | 2330 | struct task_struct *task; |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 4ba03009cf72..853cb877d5f3 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -52,7 +52,7 @@ static ssize_t | |||
52 | proc_file_read(struct file *file, char __user *buf, size_t nbytes, | 52 | proc_file_read(struct file *file, char __user *buf, size_t nbytes, |
53 | loff_t *ppos) | 53 | loff_t *ppos) |
54 | { | 54 | { |
55 | struct inode * inode = file->f_dentry->d_inode; | 55 | struct inode * inode = file->f_path.dentry->d_inode; |
56 | char *page; | 56 | char *page; |
57 | ssize_t retval=0; | 57 | ssize_t retval=0; |
58 | int eof=0; | 58 | int eof=0; |
@@ -203,7 +203,7 @@ static ssize_t | |||
203 | proc_file_write(struct file *file, const char __user *buffer, | 203 | proc_file_write(struct file *file, const char __user *buffer, |
204 | size_t count, loff_t *ppos) | 204 | size_t count, loff_t *ppos) |
205 | { | 205 | { |
206 | struct inode *inode = file->f_dentry->d_inode; | 206 | struct inode *inode = file->f_path.dentry->d_inode; |
207 | struct proc_dir_entry * dp; | 207 | struct proc_dir_entry * dp; |
208 | 208 | ||
209 | dp = PDE(inode); | 209 | dp = PDE(inode); |
@@ -432,7 +432,7 @@ int proc_readdir(struct file * filp, | |||
432 | struct proc_dir_entry * de; | 432 | struct proc_dir_entry * de; |
433 | unsigned int ino; | 433 | unsigned int ino; |
434 | int i; | 434 | int i; |
435 | struct inode *inode = filp->f_dentry->d_inode; | 435 | struct inode *inode = filp->f_path.dentry->d_inode; |
436 | int ret = 0; | 436 | int ret = 0; |
437 | 437 | ||
438 | lock_kernel(); | 438 | lock_kernel(); |
@@ -453,7 +453,7 @@ int proc_readdir(struct file * filp, | |||
453 | /* fall through */ | 453 | /* fall through */ |
454 | case 1: | 454 | case 1: |
455 | if (filldir(dirent, "..", 2, i, | 455 | if (filldir(dirent, "..", 2, i, |
456 | parent_ino(filp->f_dentry), | 456 | parent_ino(filp->f_path.dentry), |
457 | DT_DIR) < 0) | 457 | DT_DIR) < 0) |
458 | goto out; | 458 | goto out; |
459 | i++; | 459 | i++; |
@@ -558,7 +558,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de) | |||
558 | file_list_lock(); | 558 | file_list_lock(); |
559 | list_for_each(p, &sb->s_files) { | 559 | list_for_each(p, &sb->s_files) { |
560 | struct file * filp = list_entry(p, struct file, f_u.fu_list); | 560 | struct file * filp = list_entry(p, struct file, f_u.fu_list); |
561 | struct dentry * dentry = filp->f_dentry; | 561 | struct dentry * dentry = filp->f_path.dentry; |
562 | struct inode * inode; | 562 | struct inode * inode; |
563 | const struct file_operations *fops; | 563 | const struct file_operations *fops; |
564 | 564 | ||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 49dfb2ab783e..e26945ba685b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -81,14 +81,14 @@ static void proc_read_inode(struct inode * inode) | |||
81 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 81 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
82 | } | 82 | } |
83 | 83 | ||
84 | static kmem_cache_t * proc_inode_cachep; | 84 | static struct kmem_cache * proc_inode_cachep; |
85 | 85 | ||
86 | static struct inode *proc_alloc_inode(struct super_block *sb) | 86 | static struct inode *proc_alloc_inode(struct super_block *sb) |
87 | { | 87 | { |
88 | struct proc_inode *ei; | 88 | struct proc_inode *ei; |
89 | struct inode *inode; | 89 | struct inode *inode; |
90 | 90 | ||
91 | ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL); | 91 | ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL); |
92 | if (!ei) | 92 | if (!ei) |
93 | return NULL; | 93 | return NULL; |
94 | ei->pid = NULL; | 94 | ei->pid = NULL; |
@@ -105,7 +105,7 @@ static void proc_destroy_inode(struct inode *inode) | |||
105 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); | 105 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); |
106 | } | 106 | } |
107 | 107 | ||
108 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 108 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
109 | { | 109 | { |
110 | struct proc_inode *ei = (struct proc_inode *) foo; | 110 | struct proc_inode *ei = (struct proc_inode *) foo; |
111 | 111 | ||
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 1294eda4acae..1be73082edd3 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | 24 | ||
25 | #define CORE_STR "CORE" | ||
25 | 26 | ||
26 | static int open_kcore(struct inode * inode, struct file * filp) | 27 | static int open_kcore(struct inode * inode, struct file * filp) |
27 | { | 28 | { |
@@ -82,10 +83,11 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) | |||
82 | } | 83 | } |
83 | *elf_buflen = sizeof(struct elfhdr) + | 84 | *elf_buflen = sizeof(struct elfhdr) + |
84 | (*nphdr + 2)*sizeof(struct elf_phdr) + | 85 | (*nphdr + 2)*sizeof(struct elf_phdr) + |
85 | 3 * (sizeof(struct elf_note) + 4) + | 86 | 3 * ((sizeof(struct elf_note)) + |
86 | sizeof(struct elf_prstatus) + | 87 | roundup(sizeof(CORE_STR), 4)) + |
87 | sizeof(struct elf_prpsinfo) + | 88 | roundup(sizeof(struct elf_prstatus), 4) + |
88 | sizeof(struct task_struct); | 89 | roundup(sizeof(struct elf_prpsinfo), 4) + |
90 | roundup(sizeof(struct task_struct), 4); | ||
89 | *elf_buflen = PAGE_ALIGN(*elf_buflen); | 91 | *elf_buflen = PAGE_ALIGN(*elf_buflen); |
90 | return size + *elf_buflen; | 92 | return size + *elf_buflen; |
91 | } | 93 | } |
@@ -210,7 +212,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
210 | nhdr->p_offset = offset; | 212 | nhdr->p_offset = offset; |
211 | 213 | ||
212 | /* set up the process status */ | 214 | /* set up the process status */ |
213 | notes[0].name = "CORE"; | 215 | notes[0].name = CORE_STR; |
214 | notes[0].type = NT_PRSTATUS; | 216 | notes[0].type = NT_PRSTATUS; |
215 | notes[0].datasz = sizeof(struct elf_prstatus); | 217 | notes[0].datasz = sizeof(struct elf_prstatus); |
216 | notes[0].data = &prstatus; | 218 | notes[0].data = &prstatus; |
@@ -221,7 +223,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
221 | bufp = storenote(¬es[0], bufp); | 223 | bufp = storenote(¬es[0], bufp); |
222 | 224 | ||
223 | /* set up the process info */ | 225 | /* set up the process info */ |
224 | notes[1].name = "CORE"; | 226 | notes[1].name = CORE_STR; |
225 | notes[1].type = NT_PRPSINFO; | 227 | notes[1].type = NT_PRPSINFO; |
226 | notes[1].datasz = sizeof(struct elf_prpsinfo); | 228 | notes[1].datasz = sizeof(struct elf_prpsinfo); |
227 | notes[1].data = &prpsinfo; | 229 | notes[1].data = &prpsinfo; |
@@ -238,7 +240,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
238 | bufp = storenote(¬es[1], bufp); | 240 | bufp = storenote(¬es[1], bufp); |
239 | 241 | ||
240 | /* set up the task structure */ | 242 | /* set up the task structure */ |
241 | notes[2].name = "CORE"; | 243 | notes[2].name = CORE_STR; |
242 | notes[2].type = NT_TASKSTRUCT; | 244 | notes[2].type = NT_TASKSTRUCT; |
243 | notes[2].datasz = sizeof(struct task_struct); | 245 | notes[2].datasz = sizeof(struct task_struct); |
244 | notes[2].data = current; | 246 | notes[2].data = current; |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index d7dbdf9e0f49..5ec67257e5f9 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
@@ -46,7 +46,7 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | |||
46 | file = vma->vm_file; | 46 | file = vma->vm_file; |
47 | 47 | ||
48 | if (file) { | 48 | if (file) { |
49 | struct inode *inode = vma->vm_file->f_dentry->d_inode; | 49 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
50 | dev = inode->i_sb->s_dev; | 50 | dev = inode->i_sb->s_dev; |
51 | ino = inode->i_ino; | 51 | ino = inode->i_ino; |
52 | } | 52 | } |
@@ -67,7 +67,7 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | |||
67 | if (len < 1) | 67 | if (len < 1) |
68 | len = 1; | 68 | len = 1; |
69 | seq_printf(m, "%*c", len, ' '); | 69 | seq_printf(m, "%*c", len, ' '); |
70 | seq_path(m, file->f_vfsmnt, file->f_dentry, ""); | 70 | seq_path(m, file->f_path.mnt, file->f_path.dentry, ""); |
71 | } | 71 | } |
72 | 72 | ||
73 | seq_putc(m, '\n'); | 73 | seq_putc(m, '\n'); |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 93c43b676e59..b37ce33f67ea 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -39,13 +39,14 @@ | |||
39 | #include <linux/seq_file.h> | 39 | #include <linux/seq_file.h> |
40 | #include <linux/times.h> | 40 | #include <linux/times.h> |
41 | #include <linux/profile.h> | 41 | #include <linux/profile.h> |
42 | #include <linux/utsname.h> | ||
42 | #include <linux/blkdev.h> | 43 | #include <linux/blkdev.h> |
43 | #include <linux/hugetlb.h> | 44 | #include <linux/hugetlb.h> |
44 | #include <linux/jiffies.h> | 45 | #include <linux/jiffies.h> |
45 | #include <linux/sysrq.h> | 46 | #include <linux/sysrq.h> |
46 | #include <linux/vmalloc.h> | 47 | #include <linux/vmalloc.h> |
47 | #include <linux/crash_dump.h> | 48 | #include <linux/crash_dump.h> |
48 | #include <linux/pspace.h> | 49 | #include <linux/pid_namespace.h> |
49 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
50 | #include <asm/pgtable.h> | 51 | #include <asm/pgtable.h> |
51 | #include <asm/io.h> | 52 | #include <asm/io.h> |
@@ -92,7 +93,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off, | |||
92 | LOAD_INT(a), LOAD_FRAC(a), | 93 | LOAD_INT(a), LOAD_FRAC(a), |
93 | LOAD_INT(b), LOAD_FRAC(b), | 94 | LOAD_INT(b), LOAD_FRAC(b), |
94 | LOAD_INT(c), LOAD_FRAC(c), | 95 | LOAD_INT(c), LOAD_FRAC(c), |
95 | nr_running(), nr_threads, init_pspace.last_pid); | 96 | nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid); |
96 | return proc_calc_metrics(page, start, off, count, eof, len); | 97 | return proc_calc_metrics(page, start, off, count, eof, len); |
97 | } | 98 | } |
98 | 99 | ||
@@ -252,8 +253,10 @@ static int version_read_proc(char *page, char **start, off_t off, | |||
252 | { | 253 | { |
253 | int len; | 254 | int len; |
254 | 255 | ||
255 | strcpy(page, linux_banner); | 256 | len = snprintf(page, PAGE_SIZE, linux_proc_banner, |
256 | len = strlen(page); | 257 | utsname()->sysname, |
258 | utsname()->release, | ||
259 | utsname()->version); | ||
257 | return proc_calc_metrics(page, start, off, count, eof, len); | 260 | return proc_calc_metrics(page, start, off, count, eof, len); |
258 | } | 261 | } |
259 | 262 | ||
@@ -696,9 +699,11 @@ void __init proc_misc_init(void) | |||
696 | proc_symlink("mounts", NULL, "self/mounts"); | 699 | proc_symlink("mounts", NULL, "self/mounts"); |
697 | 700 | ||
698 | /* And now for trickier ones */ | 701 | /* And now for trickier ones */ |
702 | #ifdef CONFIG_PRINTK | ||
699 | entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); | 703 | entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); |
700 | if (entry) | 704 | if (entry) |
701 | entry->proc_fops = &proc_kmsg_operations; | 705 | entry->proc_fops = &proc_kmsg_operations; |
706 | #endif | ||
702 | create_seq_entry("devices", 0, &proc_devinfo_operations); | 707 | create_seq_entry("devices", 0, &proc_devinfo_operations); |
703 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); | 708 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); |
704 | #ifdef CONFIG_BLOCK | 709 | #ifdef CONFIG_BLOCK |
diff --git a/fs/proc/root.c b/fs/proc/root.c index ffe66c38488b..64d242b6dcfa 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/sched.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
18 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 6b769afac55a..55ade0d15621 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -94,8 +94,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount * | |||
94 | } | 94 | } |
95 | 95 | ||
96 | if (vma) { | 96 | if (vma) { |
97 | *mnt = mntget(vma->vm_file->f_vfsmnt); | 97 | *mnt = mntget(vma->vm_file->f_path.mnt); |
98 | *dentry = dget(vma->vm_file->f_dentry); | 98 | *dentry = dget(vma->vm_file->f_path.dentry); |
99 | result = 0; | 99 | result = 0; |
100 | } | 100 | } |
101 | 101 | ||
@@ -135,7 +135,7 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats | |||
135 | int len; | 135 | int len; |
136 | 136 | ||
137 | if (file) { | 137 | if (file) { |
138 | struct inode *inode = vma->vm_file->f_dentry->d_inode; | 138 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
139 | dev = inode->i_sb->s_dev; | 139 | dev = inode->i_sb->s_dev; |
140 | ino = inode->i_ino; | 140 | ino = inode->i_ino; |
141 | } | 141 | } |
@@ -156,7 +156,7 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats | |||
156 | */ | 156 | */ |
157 | if (file) { | 157 | if (file) { |
158 | pad_len_spaces(m, len); | 158 | pad_len_spaces(m, len); |
159 | seq_path(m, file->f_vfsmnt, file->f_dentry, "\n"); | 159 | seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n"); |
160 | } else { | 160 | } else { |
161 | const char *name = arch_vma_name(vma); | 161 | const char *name = arch_vma_name(vma); |
162 | if (!name) { | 162 | if (!name) { |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 091aa8e48e02..fcc5caf93f55 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -126,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount * | |||
126 | } | 126 | } |
127 | 127 | ||
128 | if (vma) { | 128 | if (vma) { |
129 | *mnt = mntget(vma->vm_file->f_vfsmnt); | 129 | *mnt = mntget(vma->vm_file->f_path.mnt); |
130 | *dentry = dget(vma->vm_file->f_dentry); | 130 | *dentry = dget(vma->vm_file->f_path.dentry); |
131 | result = 0; | 131 | result = 0; |
132 | } | 132 | } |
133 | 133 | ||
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c index 0d7103fa0df5..c94db1db7a71 100644 --- a/fs/qnx4/dir.c +++ b/fs/qnx4/dir.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) | 23 | static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) |
24 | { | 24 | { |
25 | struct inode *inode = filp->f_dentry->d_inode; | 25 | struct inode *inode = filp->f_path.dentry->d_inode; |
26 | unsigned int offset; | 26 | unsigned int offset; |
27 | struct buffer_head *bh; | 27 | struct buffer_head *bh; |
28 | struct qnx4_inode_entry *de; | 28 | struct qnx4_inode_entry *de; |
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 5a41db2a218d..c047dc654d5c 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -515,12 +515,12 @@ static void qnx4_read_inode(struct inode *inode) | |||
515 | brelse(bh); | 515 | brelse(bh); |
516 | } | 516 | } |
517 | 517 | ||
518 | static kmem_cache_t *qnx4_inode_cachep; | 518 | static struct kmem_cache *qnx4_inode_cachep; |
519 | 519 | ||
520 | static struct inode *qnx4_alloc_inode(struct super_block *sb) | 520 | static struct inode *qnx4_alloc_inode(struct super_block *sb) |
521 | { | 521 | { |
522 | struct qnx4_inode_info *ei; | 522 | struct qnx4_inode_info *ei; |
523 | ei = kmem_cache_alloc(qnx4_inode_cachep, SLAB_KERNEL); | 523 | ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL); |
524 | if (!ei) | 524 | if (!ei) |
525 | return NULL; | 525 | return NULL; |
526 | return &ei->vfs_inode; | 526 | return &ei->vfs_inode; |
@@ -531,7 +531,7 @@ static void qnx4_destroy_inode(struct inode *inode) | |||
531 | kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); | 531 | kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); |
532 | } | 532 | } |
533 | 533 | ||
534 | static void init_once(void *foo, kmem_cache_t * cachep, | 534 | static void init_once(void *foo, struct kmem_cache * cachep, |
535 | unsigned long flags) | 535 | unsigned long flags) |
536 | { | 536 | { |
537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; | 537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 0947fb57dcf3..54ebbc84207f 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -25,11 +25,13 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/mm.h> | ||
28 | 29 | ||
29 | const struct address_space_operations ramfs_aops = { | 30 | const struct address_space_operations ramfs_aops = { |
30 | .readpage = simple_readpage, | 31 | .readpage = simple_readpage, |
31 | .prepare_write = simple_prepare_write, | 32 | .prepare_write = simple_prepare_write, |
32 | .commit_write = simple_commit_write | 33 | .commit_write = simple_commit_write, |
34 | .set_page_dirty = __set_page_dirty_nobuffers, | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | const struct file_operations ramfs_file_operations = { | 37 | const struct file_operations ramfs_file_operations = { |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index bfe5dbf1002e..e9d6c4733282 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/mm.h> | ||
14 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
15 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -30,7 +31,8 @@ static int ramfs_nommu_setattr(struct dentry *, struct iattr *); | |||
30 | const struct address_space_operations ramfs_aops = { | 31 | const struct address_space_operations ramfs_aops = { |
31 | .readpage = simple_readpage, | 32 | .readpage = simple_readpage, |
32 | .prepare_write = simple_prepare_write, | 33 | .prepare_write = simple_prepare_write, |
33 | .commit_write = simple_commit_write | 34 | .commit_write = simple_commit_write, |
35 | .set_page_dirty = __set_page_dirty_nobuffers, | ||
34 | }; | 36 | }; |
35 | 37 | ||
36 | const struct file_operations ramfs_file_operations = { | 38 | const struct file_operations ramfs_file_operations = { |
@@ -232,7 +234,7 @@ unsigned long ramfs_nommu_get_unmapped_area(struct file *file, | |||
232 | unsigned long pgoff, unsigned long flags) | 234 | unsigned long pgoff, unsigned long flags) |
233 | { | 235 | { |
234 | unsigned long maxpages, lpages, nr, loop, ret; | 236 | unsigned long maxpages, lpages, nr, loop, ret; |
235 | struct inode *inode = file->f_dentry->d_inode; | 237 | struct inode *inode = file->f_path.dentry->d_inode; |
236 | struct page **pages = NULL, **ptr, *page; | 238 | struct page **pages = NULL, **ptr, *page; |
237 | loff_t isize; | 239 | loff_t isize; |
238 | 240 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index f792000a28e6..707ac21700d3 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -64,13 +64,13 @@ loff_t remote_llseek(struct file *file, loff_t offset, int origin) | |||
64 | lock_kernel(); | 64 | lock_kernel(); |
65 | switch (origin) { | 65 | switch (origin) { |
66 | case 2: | 66 | case 2: |
67 | offset += i_size_read(file->f_dentry->d_inode); | 67 | offset += i_size_read(file->f_path.dentry->d_inode); |
68 | break; | 68 | break; |
69 | case 1: | 69 | case 1: |
70 | offset += file->f_pos; | 70 | offset += file->f_pos; |
71 | } | 71 | } |
72 | retval = -EINVAL; | 72 | retval = -EINVAL; |
73 | if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) { | 73 | if (offset>=0 && offset<=file->f_path.dentry->d_inode->i_sb->s_maxbytes) { |
74 | if (offset != file->f_pos) { | 74 | if (offset != file->f_pos) { |
75 | file->f_pos = offset; | 75 | file->f_pos = offset; |
76 | file->f_version = 0; | 76 | file->f_version = 0; |
@@ -95,7 +95,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) | |||
95 | lock_kernel(); | 95 | lock_kernel(); |
96 | switch (origin) { | 96 | switch (origin) { |
97 | case 2: | 97 | case 2: |
98 | offset += i_size_read(file->f_dentry->d_inode); | 98 | offset += i_size_read(file->f_path.dentry->d_inode); |
99 | break; | 99 | break; |
100 | case 1: | 100 | case 1: |
101 | offset += file->f_pos; | 101 | offset += file->f_pos; |
@@ -203,7 +203,7 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count | |||
203 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) | 203 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) |
204 | goto Einval; | 204 | goto Einval; |
205 | 205 | ||
206 | inode = file->f_dentry->d_inode; | 206 | inode = file->f_path.dentry->d_inode; |
207 | if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) { | 207 | if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) { |
208 | int retval = locks_mandatory_area( | 208 | int retval = locks_mandatory_area( |
209 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, | 209 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, |
@@ -273,7 +273,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | |||
273 | else | 273 | else |
274 | ret = do_sync_read(file, buf, count, pos); | 274 | ret = do_sync_read(file, buf, count, pos); |
275 | if (ret > 0) { | 275 | if (ret > 0) { |
276 | fsnotify_access(file->f_dentry); | 276 | fsnotify_access(file->f_path.dentry); |
277 | current->rchar += ret; | 277 | current->rchar += ret; |
278 | } | 278 | } |
279 | current->syscr++; | 279 | current->syscr++; |
@@ -331,7 +331,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
331 | else | 331 | else |
332 | ret = do_sync_write(file, buf, count, pos); | 332 | ret = do_sync_write(file, buf, count, pos); |
333 | if (ret > 0) { | 333 | if (ret > 0) { |
334 | fsnotify_modify(file->f_dentry); | 334 | fsnotify_modify(file->f_path.dentry); |
335 | current->wchar += ret; | 335 | current->wchar += ret; |
336 | } | 336 | } |
337 | current->syscw++; | 337 | current->syscw++; |
@@ -450,8 +450,6 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) | |||
450 | return seg; | 450 | return seg; |
451 | } | 451 | } |
452 | 452 | ||
453 | EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */ | ||
454 | |||
455 | ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, | 453 | ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, |
456 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) | 454 | unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) |
457 | { | 455 | { |
@@ -628,9 +626,9 @@ out: | |||
628 | kfree(iov); | 626 | kfree(iov); |
629 | if ((ret + (type == READ)) > 0) { | 627 | if ((ret + (type == READ)) > 0) { |
630 | if (type == READ) | 628 | if (type == READ) |
631 | fsnotify_access(file->f_dentry); | 629 | fsnotify_access(file->f_path.dentry); |
632 | else | 630 | else |
633 | fsnotify_modify(file->f_dentry); | 631 | fsnotify_modify(file->f_path.dentry); |
634 | } | 632 | } |
635 | return ret; | 633 | return ret; |
636 | } | 634 | } |
@@ -722,7 +720,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
722 | if (!(in_file->f_mode & FMODE_READ)) | 720 | if (!(in_file->f_mode & FMODE_READ)) |
723 | goto fput_in; | 721 | goto fput_in; |
724 | retval = -EINVAL; | 722 | retval = -EINVAL; |
725 | in_inode = in_file->f_dentry->d_inode; | 723 | in_inode = in_file->f_path.dentry->d_inode; |
726 | if (!in_inode) | 724 | if (!in_inode) |
727 | goto fput_in; | 725 | goto fput_in; |
728 | if (!in_file->f_op || !in_file->f_op->sendfile) | 726 | if (!in_file->f_op || !in_file->f_op->sendfile) |
@@ -754,7 +752,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
754 | retval = -EINVAL; | 752 | retval = -EINVAL; |
755 | if (!out_file->f_op || !out_file->f_op->sendpage) | 753 | if (!out_file->f_op || !out_file->f_op->sendpage) |
756 | goto fput_out; | 754 | goto fput_out; |
757 | out_inode = out_file->f_dentry->d_inode; | 755 | out_inode = out_file->f_path.dentry->d_inode; |
758 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); | 756 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); |
759 | if (retval < 0) | 757 | if (retval < 0) |
760 | goto fput_out; | 758 | goto fput_out; |
diff --git a/fs/readdir.c b/fs/readdir.c index bff3ee58e2f8..f39f5b313252 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | int vfs_readdir(struct file *file, filldir_t filler, void *buf) | 22 | int vfs_readdir(struct file *file, filldir_t filler, void *buf) |
23 | { | 23 | { |
24 | struct inode *inode = file->f_dentry->d_inode; | 24 | struct inode *inode = file->f_path.dentry->d_inode; |
25 | int res = -ENOTDIR; | 25 | int res = -ENOTDIR; |
26 | if (!file->f_op || !file->f_op->readdir) | 26 | if (!file->f_op || !file->f_op->readdir) |
27 | goto out; | 27 | goto out; |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index e3d466a228d4..b286ccb08587 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -708,7 +708,7 @@ static void oid_groups(reiserfs_blocknr_hint_t * hint) | |||
708 | */ | 708 | */ |
709 | static int get_left_neighbor(reiserfs_blocknr_hint_t * hint) | 709 | static int get_left_neighbor(reiserfs_blocknr_hint_t * hint) |
710 | { | 710 | { |
711 | struct path *path; | 711 | struct treepath *path; |
712 | struct buffer_head *bh; | 712 | struct buffer_head *bh; |
713 | struct item_head *ih; | 713 | struct item_head *ih; |
714 | int pos_in_item; | 714 | int pos_in_item; |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 657050ad7430..96a2f8889da3 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -45,7 +45,7 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, | |||
45 | // | 45 | // |
46 | static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 46 | static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
47 | { | 47 | { |
48 | struct inode *inode = filp->f_dentry->d_inode; | 48 | struct inode *inode = filp->f_path.dentry->d_inode; |
49 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 49 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
50 | INITIALIZE_PATH(path_to_entry); | 50 | INITIALIZE_PATH(path_to_entry); |
51 | struct buffer_head *bh; | 51 | struct buffer_head *bh; |
@@ -135,7 +135,7 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
135 | /* Ignore the .reiserfs_priv entry */ | 135 | /* Ignore the .reiserfs_priv entry */ |
136 | if (reiserfs_xattrs(inode->i_sb) && | 136 | if (reiserfs_xattrs(inode->i_sb) && |
137 | !old_format_only(inode->i_sb) && | 137 | !old_format_only(inode->i_sb) && |
138 | filp->f_dentry == inode->i_sb->s_root && | 138 | filp->f_path.dentry == inode->i_sb->s_root && |
139 | REISERFS_SB(inode->i_sb)->priv_root && | 139 | REISERFS_SB(inode->i_sb)->priv_root && |
140 | REISERFS_SB(inode->i_sb)->priv_root->d_inode | 140 | REISERFS_SB(inode->i_sb)->priv_root->d_inode |
141 | && deh_objectid(deh) == | 141 | && deh_objectid(deh) == |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index ac14318c81ba..99b6f329ba23 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -317,12 +317,11 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
317 | /* area filled with zeroes, to supply as list of zero blocknumbers | 317 | /* area filled with zeroes, to supply as list of zero blocknumbers |
318 | We allocate it outside of loop just in case loop would spin for | 318 | We allocate it outside of loop just in case loop would spin for |
319 | several iterations. */ | 319 | several iterations. */ |
320 | char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. | 320 | char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. |
321 | if (!zeros) { | 321 | if (!zeros) { |
322 | res = -ENOMEM; | 322 | res = -ENOMEM; |
323 | goto error_exit_free_blocks; | 323 | goto error_exit_free_blocks; |
324 | } | 324 | } |
325 | memset(zeros, 0, to_paste * UNFM_P_SIZE); | ||
326 | do { | 325 | do { |
327 | to_paste = | 326 | to_paste = |
328 | min_t(__u64, hole_size, | 327 | min_t(__u64, hole_size, |
@@ -407,6 +406,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
407 | we restart it. This will also free the path. */ | 406 | we restart it. This will also free the path. */ |
408 | if (journal_transaction_should_end | 407 | if (journal_transaction_should_end |
409 | (th, th->t_blocks_allocated)) { | 408 | (th, th->t_blocks_allocated)) { |
409 | inode->i_size = cpu_key_k_offset(&key) + | ||
410 | (to_paste << inode->i_blkbits); | ||
410 | res = | 411 | res = |
411 | restart_transaction(th, inode, | 412 | restart_transaction(th, inode, |
412 | &path); | 413 | &path); |
@@ -1045,6 +1046,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1045 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); | 1046 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); |
1046 | memset(kaddr, 0, from); | 1047 | memset(kaddr, 0, from); |
1047 | kunmap_atomic(kaddr, KM_USER0); | 1048 | kunmap_atomic(kaddr, KM_USER0); |
1049 | flush_dcache_page(prepared_pages[0]); | ||
1048 | } | 1050 | } |
1049 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ | 1051 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ |
1050 | char *kaddr = | 1052 | char *kaddr = |
@@ -1052,6 +1054,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1052 | KM_USER0); | 1054 | KM_USER0); |
1053 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); | 1055 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); |
1054 | kunmap_atomic(kaddr, KM_USER0); | 1056 | kunmap_atomic(kaddr, KM_USER0); |
1057 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1055 | } | 1058 | } |
1056 | 1059 | ||
1057 | /* Since all blocks are new - use already calculated value */ | 1060 | /* Since all blocks are new - use already calculated value */ |
@@ -1185,6 +1188,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1185 | memset(kaddr + block_start, 0, | 1188 | memset(kaddr + block_start, 0, |
1186 | from - block_start); | 1189 | from - block_start); |
1187 | kunmap_atomic(kaddr, KM_USER0); | 1190 | kunmap_atomic(kaddr, KM_USER0); |
1191 | flush_dcache_page(prepared_pages[0]); | ||
1188 | set_buffer_uptodate(bh); | 1192 | set_buffer_uptodate(bh); |
1189 | } | 1193 | } |
1190 | } | 1194 | } |
@@ -1222,6 +1226,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1222 | KM_USER0); | 1226 | KM_USER0); |
1223 | memset(kaddr + to, 0, block_end - to); | 1227 | memset(kaddr + to, 0, block_end - to); |
1224 | kunmap_atomic(kaddr, KM_USER0); | 1228 | kunmap_atomic(kaddr, KM_USER0); |
1229 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1225 | set_buffer_uptodate(bh); | 1230 | set_buffer_uptodate(bh); |
1226 | } | 1231 | } |
1227 | } | 1232 | } |
@@ -1283,7 +1288,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1283 | loff_t pos; // Current position in the file. | 1288 | loff_t pos; // Current position in the file. |
1284 | ssize_t res; // return value of various functions that we call. | 1289 | ssize_t res; // return value of various functions that we call. |
1285 | int err = 0; | 1290 | int err = 0; |
1286 | struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to. | 1291 | struct inode *inode = file->f_path.dentry->d_inode; // Inode of the file that we are writing to. |
1287 | /* To simplify coding at this time, we store | 1292 | /* To simplify coding at this time, we store |
1288 | locked pages in array for now */ | 1293 | locked pages in array for now */ |
1289 | struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME]; | 1294 | struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME]; |
@@ -1307,56 +1312,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1307 | count = MAX_NON_LFS - (unsigned long)*ppos; | 1312 | count = MAX_NON_LFS - (unsigned long)*ppos; |
1308 | } | 1313 | } |
1309 | 1314 | ||
1310 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment | 1315 | if (file->f_flags & O_DIRECT) |
1311 | ssize_t result, after_file_end = 0; | 1316 | return do_sync_write(file, buf, count, ppos); |
1312 | if ((*ppos + count >= inode->i_size) | ||
1313 | || (file->f_flags & O_APPEND)) { | ||
1314 | /* If we are appending a file, we need to put this savelink in here. | ||
1315 | If we will crash while doing direct io, finish_unfinished will | ||
1316 | cut the garbage from the file end. */ | ||
1317 | reiserfs_write_lock(inode->i_sb); | ||
1318 | err = | ||
1319 | journal_begin(&th, inode->i_sb, | ||
1320 | JOURNAL_PER_BALANCE_CNT); | ||
1321 | if (err) { | ||
1322 | reiserfs_write_unlock(inode->i_sb); | ||
1323 | return err; | ||
1324 | } | ||
1325 | reiserfs_update_inode_transaction(inode); | ||
1326 | add_save_link(&th, inode, 1 /* Truncate */ ); | ||
1327 | after_file_end = 1; | ||
1328 | err = | ||
1329 | journal_end(&th, inode->i_sb, | ||
1330 | JOURNAL_PER_BALANCE_CNT); | ||
1331 | reiserfs_write_unlock(inode->i_sb); | ||
1332 | if (err) | ||
1333 | return err; | ||
1334 | } | ||
1335 | result = do_sync_write(file, buf, count, ppos); | ||
1336 | |||
1337 | if (after_file_end) { /* Now update i_size and remove the savelink */ | ||
1338 | struct reiserfs_transaction_handle th; | ||
1339 | reiserfs_write_lock(inode->i_sb); | ||
1340 | err = journal_begin(&th, inode->i_sb, 1); | ||
1341 | if (err) { | ||
1342 | reiserfs_write_unlock(inode->i_sb); | ||
1343 | return err; | ||
1344 | } | ||
1345 | reiserfs_update_inode_transaction(inode); | ||
1346 | mark_inode_dirty(inode); | ||
1347 | err = journal_end(&th, inode->i_sb, 1); | ||
1348 | if (err) { | ||
1349 | reiserfs_write_unlock(inode->i_sb); | ||
1350 | return err; | ||
1351 | } | ||
1352 | err = remove_save_link(inode, 1 /* truncate */ ); | ||
1353 | reiserfs_write_unlock(inode->i_sb); | ||
1354 | if (err) | ||
1355 | return err; | ||
1356 | } | ||
1357 | |||
1358 | return result; | ||
1359 | } | ||
1360 | 1317 | ||
1361 | if (unlikely((ssize_t) count < 0)) | 1318 | if (unlikely((ssize_t) count < 0)) |
1362 | return -EINVAL; | 1319 | return -EINVAL; |
@@ -1378,7 +1335,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1378 | if (count == 0) | 1335 | if (count == 0) |
1379 | goto out; | 1336 | goto out; |
1380 | 1337 | ||
1381 | res = remove_suid(file->f_dentry); | 1338 | res = remove_suid(file->f_path.dentry); |
1382 | if (res) | 1339 | if (res) |
1383 | goto out; | 1340 | goto out; |
1384 | 1341 | ||
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 6d0e554daa9d..0ee35c6c9b72 100644 --- a/fs/reiserfs/fix_node.c +++ b/fs/reiserfs/fix_node.c | |||
@@ -957,7 +957,7 @@ static int get_far_parent(struct tree_balance *p_s_tb, | |||
957 | { | 957 | { |
958 | struct buffer_head *p_s_parent; | 958 | struct buffer_head *p_s_parent; |
959 | INITIALIZE_PATH(s_path_to_neighbor_father); | 959 | INITIALIZE_PATH(s_path_to_neighbor_father); |
960 | struct path *p_s_path = p_s_tb->tb_path; | 960 | struct treepath *p_s_path = p_s_tb->tb_path; |
961 | struct cpu_key s_lr_father_key; | 961 | struct cpu_key s_lr_father_key; |
962 | int n_counter, | 962 | int n_counter, |
963 | n_position = INT_MAX, | 963 | n_position = INT_MAX, |
@@ -1074,7 +1074,7 @@ static int get_far_parent(struct tree_balance *p_s_tb, | |||
1074 | */ | 1074 | */ |
1075 | static int get_parents(struct tree_balance *p_s_tb, int n_h) | 1075 | static int get_parents(struct tree_balance *p_s_tb, int n_h) |
1076 | { | 1076 | { |
1077 | struct path *p_s_path = p_s_tb->tb_path; | 1077 | struct treepath *p_s_path = p_s_tb->tb_path; |
1078 | int n_position, | 1078 | int n_position, |
1079 | n_ret_value, | 1079 | n_ret_value, |
1080 | n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h); | 1080 | n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h); |
@@ -1885,7 +1885,7 @@ static int check_balance(int mode, | |||
1885 | static int get_direct_parent(struct tree_balance *p_s_tb, int n_h) | 1885 | static int get_direct_parent(struct tree_balance *p_s_tb, int n_h) |
1886 | { | 1886 | { |
1887 | struct buffer_head *p_s_bh; | 1887 | struct buffer_head *p_s_bh; |
1888 | struct path *p_s_path = p_s_tb->tb_path; | 1888 | struct treepath *p_s_path = p_s_tb->tb_path; |
1889 | int n_position, | 1889 | int n_position, |
1890 | n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h); | 1890 | n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h); |
1891 | 1891 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 9c69bcacad22..f3d1c4a77979 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -207,7 +207,7 @@ static int file_capable(struct inode *inode, long block) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | /*static*/ int restart_transaction(struct reiserfs_transaction_handle *th, | 209 | /*static*/ int restart_transaction(struct reiserfs_transaction_handle *th, |
210 | struct inode *inode, struct path *path) | 210 | struct inode *inode, struct treepath *path) |
211 | { | 211 | { |
212 | struct super_block *s = th->t_super; | 212 | struct super_block *s = th->t_super; |
213 | int len = th->t_blocks_allocated; | 213 | int len = th->t_blocks_allocated; |
@@ -216,11 +216,12 @@ static int file_capable(struct inode *inode, long block) | |||
216 | BUG_ON(!th->t_trans_id); | 216 | BUG_ON(!th->t_trans_id); |
217 | BUG_ON(!th->t_refcount); | 217 | BUG_ON(!th->t_refcount); |
218 | 218 | ||
219 | pathrelse(path); | ||
220 | |||
219 | /* we cannot restart while nested */ | 221 | /* we cannot restart while nested */ |
220 | if (th->t_refcount > 1) { | 222 | if (th->t_refcount > 1) { |
221 | return 0; | 223 | return 0; |
222 | } | 224 | } |
223 | pathrelse(path); | ||
224 | reiserfs_update_sd(th, inode); | 225 | reiserfs_update_sd(th, inode); |
225 | err = journal_end(th, s, len); | 226 | err = journal_end(th, s, len); |
226 | if (!err) { | 227 | if (!err) { |
@@ -569,7 +570,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th, | |||
569 | long block, | 570 | long block, |
570 | struct inode *inode, | 571 | struct inode *inode, |
571 | b_blocknr_t * allocated_block_nr, | 572 | b_blocknr_t * allocated_block_nr, |
572 | struct path *path, int flags) | 573 | struct treepath *path, int flags) |
573 | { | 574 | { |
574 | BUG_ON(!th->t_trans_id); | 575 | BUG_ON(!th->t_trans_id); |
575 | 576 | ||
@@ -928,15 +929,12 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
928 | if (blocks_needed == 1) { | 929 | if (blocks_needed == 1) { |
929 | un = &unf_single; | 930 | un = &unf_single; |
930 | } else { | 931 | } else { |
931 | un = kmalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. | 932 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. |
932 | if (!un) { | 933 | if (!un) { |
933 | un = &unf_single; | 934 | un = &unf_single; |
934 | blocks_needed = 1; | 935 | blocks_needed = 1; |
935 | max_to_insert = 0; | 936 | max_to_insert = 0; |
936 | } else | 937 | } |
937 | memset(un, 0, | ||
938 | UNFM_P_SIZE * min(blocks_needed, | ||
939 | max_to_insert)); | ||
940 | } | 938 | } |
941 | if (blocks_needed <= max_to_insert) { | 939 | if (blocks_needed <= max_to_insert) { |
942 | /* we are going to add target block to the file. Use allocated | 940 | /* we are going to add target block to the file. Use allocated |
@@ -1109,7 +1107,7 @@ static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size) | |||
1109 | // | 1107 | // |
1110 | 1108 | ||
1111 | // called by read_locked_inode | 1109 | // called by read_locked_inode |
1112 | static void init_inode(struct inode *inode, struct path *path) | 1110 | static void init_inode(struct inode *inode, struct treepath *path) |
1113 | { | 1111 | { |
1114 | struct buffer_head *bh; | 1112 | struct buffer_head *bh; |
1115 | struct item_head *ih; | 1113 | struct item_head *ih; |
@@ -1286,7 +1284,7 @@ static void inode2sd_v1(void *sd, struct inode *inode, loff_t size) | |||
1286 | /* NOTE, you must prepare the buffer head before sending it here, | 1284 | /* NOTE, you must prepare the buffer head before sending it here, |
1287 | ** and then log it after the call | 1285 | ** and then log it after the call |
1288 | */ | 1286 | */ |
1289 | static void update_stat_data(struct path *path, struct inode *inode, | 1287 | static void update_stat_data(struct treepath *path, struct inode *inode, |
1290 | loff_t size) | 1288 | loff_t size) |
1291 | { | 1289 | { |
1292 | struct buffer_head *bh; | 1290 | struct buffer_head *bh; |
@@ -1655,7 +1653,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync) | |||
1655 | containing "." and ".." entries */ | 1653 | containing "." and ".." entries */ |
1656 | static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, | 1654 | static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, |
1657 | struct inode *inode, | 1655 | struct inode *inode, |
1658 | struct item_head *ih, struct path *path, | 1656 | struct item_head *ih, struct treepath *path, |
1659 | struct inode *dir) | 1657 | struct inode *dir) |
1660 | { | 1658 | { |
1661 | struct super_block *sb = th->t_super; | 1659 | struct super_block *sb = th->t_super; |
@@ -1714,7 +1712,7 @@ static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, | |||
1714 | containing the body of symlink */ | 1712 | containing the body of symlink */ |
1715 | static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode, /* Inode of symlink */ | 1713 | static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode, /* Inode of symlink */ |
1716 | struct item_head *ih, | 1714 | struct item_head *ih, |
1717 | struct path *path, const char *symname, | 1715 | struct treepath *path, const char *symname, |
1718 | int item_len) | 1716 | int item_len) |
1719 | { | 1717 | { |
1720 | struct super_block *sb = th->t_super; | 1718 | struct super_block *sb = th->t_super; |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 9c57578cb831..b484d2913c0d 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -99,7 +99,7 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
99 | long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, | 99 | long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, |
100 | unsigned long arg) | 100 | unsigned long arg) |
101 | { | 101 | { |
102 | struct inode *inode = file->f_dentry->d_inode; | 102 | struct inode *inode = file->f_path.dentry->d_inode; |
103 | int ret; | 103 | int ret; |
104 | 104 | ||
105 | /* These are just misnamed, they actually get/put from/to user an int */ | 105 | /* These are just misnamed, they actually get/put from/to user an int */ |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 85ce23268302..7280a23ef344 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -104,7 +104,7 @@ static int release_journal_dev(struct super_block *super, | |||
104 | struct reiserfs_journal *journal); | 104 | struct reiserfs_journal *journal); |
105 | static int dirty_one_transaction(struct super_block *s, | 105 | static int dirty_one_transaction(struct super_block *s, |
106 | struct reiserfs_journal_list *jl); | 106 | struct reiserfs_journal_list *jl); |
107 | static void flush_async_commits(void *p); | 107 | static void flush_async_commits(struct work_struct *work); |
108 | static void queue_log_writer(struct super_block *s); | 108 | static void queue_log_writer(struct super_block *s); |
109 | 109 | ||
110 | /* values for join in do_journal_begin_r */ | 110 | /* values for join in do_journal_begin_r */ |
@@ -1464,7 +1464,7 @@ static int flush_journal_list(struct super_block *s, | |||
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | /* if someone has this block in a newer transaction, just make | 1466 | /* if someone has this block in a newer transaction, just make |
1467 | ** sure they are commited, and don't try writing it to disk | 1467 | ** sure they are committed, and don't try writing it to disk |
1468 | */ | 1468 | */ |
1469 | if (pjl) { | 1469 | if (pjl) { |
1470 | if (atomic_read(&pjl->j_commit_left)) | 1470 | if (atomic_read(&pjl->j_commit_left)) |
@@ -2836,7 +2836,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2836 | if (reiserfs_mounted_fs_count <= 1) | 2836 | if (reiserfs_mounted_fs_count <= 1) |
2837 | commit_wq = create_workqueue("reiserfs"); | 2837 | commit_wq = create_workqueue("reiserfs"); |
2838 | 2838 | ||
2839 | INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb); | 2839 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); |
2840 | journal->j_work_sb = p_s_sb; | ||
2840 | return 0; | 2841 | return 0; |
2841 | free_and_return: | 2842 | free_and_return: |
2842 | free_journal_ram(p_s_sb); | 2843 | free_journal_ram(p_s_sb); |
@@ -3384,7 +3385,7 @@ static int remove_from_transaction(struct super_block *p_s_sb, | |||
3384 | 3385 | ||
3385 | /* | 3386 | /* |
3386 | ** for any cnode in a journal list, it can only be dirtied of all the | 3387 | ** for any cnode in a journal list, it can only be dirtied of all the |
3387 | ** transactions that include it are commited to disk. | 3388 | ** transactions that include it are committed to disk. |
3388 | ** this checks through each transaction, and returns 1 if you are allowed to dirty, | 3389 | ** this checks through each transaction, and returns 1 if you are allowed to dirty, |
3389 | ** and 0 if you aren't | 3390 | ** and 0 if you aren't |
3390 | ** | 3391 | ** |
@@ -3426,7 +3427,7 @@ static int can_dirty(struct reiserfs_journal_cnode *cn) | |||
3426 | } | 3427 | } |
3427 | 3428 | ||
3428 | /* syncs the commit blocks, but does not force the real buffers to disk | 3429 | /* syncs the commit blocks, but does not force the real buffers to disk |
3429 | ** will wait until the current transaction is done/commited before returning | 3430 | ** will wait until the current transaction is done/committed before returning |
3430 | */ | 3431 | */ |
3431 | int journal_end_sync(struct reiserfs_transaction_handle *th, | 3432 | int journal_end_sync(struct reiserfs_transaction_handle *th, |
3432 | struct super_block *p_s_sb, unsigned long nblocks) | 3433 | struct super_block *p_s_sb, unsigned long nblocks) |
@@ -3447,10 +3448,11 @@ int journal_end_sync(struct reiserfs_transaction_handle *th, | |||
3447 | /* | 3448 | /* |
3448 | ** writeback the pending async commits to disk | 3449 | ** writeback the pending async commits to disk |
3449 | */ | 3450 | */ |
3450 | static void flush_async_commits(void *p) | 3451 | static void flush_async_commits(struct work_struct *work) |
3451 | { | 3452 | { |
3452 | struct super_block *p_s_sb = p; | 3453 | struct reiserfs_journal *journal = |
3453 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 3454 | container_of(work, struct reiserfs_journal, j_work.work); |
3455 | struct super_block *p_s_sb = journal->j_work_sb; | ||
3454 | struct reiserfs_journal_list *jl; | 3456 | struct reiserfs_journal_list *jl; |
3455 | struct list_head *entry; | 3457 | struct list_head *entry; |
3456 | 3458 | ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index abde1edc2235..23f5cd5bbf56 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -54,7 +54,7 @@ static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off) | |||
54 | 54 | ||
55 | // comment? maybe something like set de to point to what the path points to? | 55 | // comment? maybe something like set de to point to what the path points to? |
56 | static inline void set_de_item_location(struct reiserfs_dir_entry *de, | 56 | static inline void set_de_item_location(struct reiserfs_dir_entry *de, |
57 | struct path *path) | 57 | struct treepath *path) |
58 | { | 58 | { |
59 | de->de_bh = get_last_bh(path); | 59 | de->de_bh = get_last_bh(path); |
60 | de->de_ih = get_ih(path); | 60 | de->de_ih = get_ih(path); |
@@ -113,7 +113,7 @@ entry position in the item | |||
113 | 113 | ||
114 | /* The function is NOT SCHEDULE-SAFE! */ | 114 | /* The function is NOT SCHEDULE-SAFE! */ |
115 | int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, | 115 | int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, |
116 | struct path *path, struct reiserfs_dir_entry *de) | 116 | struct treepath *path, struct reiserfs_dir_entry *de) |
117 | { | 117 | { |
118 | int retval; | 118 | int retval; |
119 | 119 | ||
@@ -282,7 +282,7 @@ static int linear_search_in_dir_item(struct cpu_key *key, | |||
282 | // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND | 282 | // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND |
283 | // FIXME: should add something like IOERROR | 283 | // FIXME: should add something like IOERROR |
284 | static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, | 284 | static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, |
285 | struct path *path_to_entry, | 285 | struct treepath *path_to_entry, |
286 | struct reiserfs_dir_entry *de) | 286 | struct reiserfs_dir_entry *de) |
287 | { | 287 | { |
288 | struct cpu_key key_to_search; | 288 | struct cpu_key key_to_search; |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index c533ec1bcaec..ecc9943202fc 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -295,7 +295,7 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb) | |||
295 | } | 295 | } |
296 | #if defined( REISERFS_USE_OIDMAPF ) | 296 | #if defined( REISERFS_USE_OIDMAPF ) |
297 | if (sb_info->oidmap.use_file && (sb_info->oidmap.mapf != NULL)) { | 297 | if (sb_info->oidmap.use_file && (sb_info->oidmap.mapf != NULL)) { |
298 | loff_t size = sb_info->oidmap.mapf->f_dentry->d_inode->i_size; | 298 | loff_t size = sb_info->oidmap.mapf->f_path.dentry->d_inode->i_size; |
299 | total_used += size / sizeof(reiserfs_oidinterval_d_t); | 299 | total_used += size / sizeof(reiserfs_oidinterval_d_t); |
300 | } | 300 | } |
301 | #endif | 301 | #endif |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 5240abe1a709..afb21ea45302 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -244,7 +244,7 @@ static const struct reiserfs_key MAX_KEY = { | |||
244 | of the path, and going upwards. We must check the path's validity at each step. If the key is not in | 244 | of the path, and going upwards. We must check the path's validity at each step. If the key is not in |
245 | the path, there is no delimiting key in the tree (buffer is first or last buffer in tree), and in this | 245 | the path, there is no delimiting key in the tree (buffer is first or last buffer in tree), and in this |
246 | case we return a special key, either MIN_KEY or MAX_KEY. */ | 246 | case we return a special key, either MIN_KEY or MAX_KEY. */ |
247 | static inline const struct reiserfs_key *get_lkey(const struct path | 247 | static inline const struct reiserfs_key *get_lkey(const struct treepath |
248 | *p_s_chk_path, | 248 | *p_s_chk_path, |
249 | const struct super_block | 249 | const struct super_block |
250 | *p_s_sb) | 250 | *p_s_sb) |
@@ -290,7 +290,7 @@ static inline const struct reiserfs_key *get_lkey(const struct path | |||
290 | } | 290 | } |
291 | 291 | ||
292 | /* Get delimiting key of the buffer at the path and its right neighbor. */ | 292 | /* Get delimiting key of the buffer at the path and its right neighbor. */ |
293 | inline const struct reiserfs_key *get_rkey(const struct path *p_s_chk_path, | 293 | inline const struct reiserfs_key *get_rkey(const struct treepath *p_s_chk_path, |
294 | const struct super_block *p_s_sb) | 294 | const struct super_block *p_s_sb) |
295 | { | 295 | { |
296 | int n_position, n_path_offset = p_s_chk_path->path_length; | 296 | int n_position, n_path_offset = p_s_chk_path->path_length; |
@@ -337,7 +337,7 @@ inline const struct reiserfs_key *get_rkey(const struct path *p_s_chk_path, | |||
337 | the path. These delimiting keys are stored at least one level above that buffer in the tree. If the | 337 | the path. These delimiting keys are stored at least one level above that buffer in the tree. If the |
338 | buffer is the first or last node in the tree order then one of the delimiting keys may be absent, and in | 338 | buffer is the first or last node in the tree order then one of the delimiting keys may be absent, and in |
339 | this case get_lkey and get_rkey return a special key which is MIN_KEY or MAX_KEY. */ | 339 | this case get_lkey and get_rkey return a special key which is MIN_KEY or MAX_KEY. */ |
340 | static inline int key_in_buffer(struct path *p_s_chk_path, /* Path which should be checked. */ | 340 | static inline int key_in_buffer(struct treepath *p_s_chk_path, /* Path which should be checked. */ |
341 | const struct cpu_key *p_s_key, /* Key which should be checked. */ | 341 | const struct cpu_key *p_s_key, /* Key which should be checked. */ |
342 | struct super_block *p_s_sb /* Super block pointer. */ | 342 | struct super_block *p_s_sb /* Super block pointer. */ |
343 | ) | 343 | ) |
@@ -374,7 +374,7 @@ inline void decrement_bcount(struct buffer_head *p_s_bh) | |||
374 | } | 374 | } |
375 | 375 | ||
376 | /* Decrement b_count field of the all buffers in the path. */ | 376 | /* Decrement b_count field of the all buffers in the path. */ |
377 | void decrement_counters_in_path(struct path *p_s_search_path) | 377 | void decrement_counters_in_path(struct treepath *p_s_search_path) |
378 | { | 378 | { |
379 | int n_path_offset = p_s_search_path->path_length; | 379 | int n_path_offset = p_s_search_path->path_length; |
380 | 380 | ||
@@ -391,7 +391,7 @@ void decrement_counters_in_path(struct path *p_s_search_path) | |||
391 | p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; | 391 | p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; |
392 | } | 392 | } |
393 | 393 | ||
394 | int reiserfs_check_path(struct path *p) | 394 | int reiserfs_check_path(struct treepath *p) |
395 | { | 395 | { |
396 | RFALSE(p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET, | 396 | RFALSE(p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET, |
397 | "path not properly relsed"); | 397 | "path not properly relsed"); |
@@ -403,7 +403,7 @@ int reiserfs_check_path(struct path *p) | |||
403 | ** | 403 | ** |
404 | ** only called from fix_nodes() | 404 | ** only called from fix_nodes() |
405 | */ | 405 | */ |
406 | void pathrelse_and_restore(struct super_block *s, struct path *p_s_search_path) | 406 | void pathrelse_and_restore(struct super_block *s, struct treepath *p_s_search_path) |
407 | { | 407 | { |
408 | int n_path_offset = p_s_search_path->path_length; | 408 | int n_path_offset = p_s_search_path->path_length; |
409 | 409 | ||
@@ -421,7 +421,7 @@ void pathrelse_and_restore(struct super_block *s, struct path *p_s_search_path) | |||
421 | } | 421 | } |
422 | 422 | ||
423 | /* Release all buffers in the path. */ | 423 | /* Release all buffers in the path. */ |
424 | void pathrelse(struct path *p_s_search_path) | 424 | void pathrelse(struct treepath *p_s_search_path) |
425 | { | 425 | { |
426 | int n_path_offset = p_s_search_path->path_length; | 426 | int n_path_offset = p_s_search_path->path_length; |
427 | 427 | ||
@@ -602,7 +602,7 @@ static void search_by_key_reada(struct super_block *s, | |||
602 | correctness of the bottom of the path */ | 602 | correctness of the bottom of the path */ |
603 | /* The function is NOT SCHEDULE-SAFE! */ | 603 | /* The function is NOT SCHEDULE-SAFE! */ |
604 | int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* Key to search. */ | 604 | int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* Key to search. */ |
605 | struct path *p_s_search_path, /* This structure was | 605 | struct treepath *p_s_search_path,/* This structure was |
606 | allocated and initialized | 606 | allocated and initialized |
607 | by the calling | 607 | by the calling |
608 | function. It is filled up | 608 | function. It is filled up |
@@ -813,7 +813,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* | |||
813 | /* The function is NOT SCHEDULE-SAFE! */ | 813 | /* The function is NOT SCHEDULE-SAFE! */ |
814 | int search_for_position_by_key(struct super_block *p_s_sb, /* Pointer to the super block. */ | 814 | int search_for_position_by_key(struct super_block *p_s_sb, /* Pointer to the super block. */ |
815 | const struct cpu_key *p_cpu_key, /* Key to search (cpu variable) */ | 815 | const struct cpu_key *p_cpu_key, /* Key to search (cpu variable) */ |
816 | struct path *p_s_search_path /* Filled up by this function. */ | 816 | struct treepath *p_s_search_path /* Filled up by this function. */ |
817 | ) | 817 | ) |
818 | { | 818 | { |
819 | struct item_head *p_le_ih; /* pointer to on-disk structure */ | 819 | struct item_head *p_le_ih; /* pointer to on-disk structure */ |
@@ -884,7 +884,7 @@ int search_for_position_by_key(struct super_block *p_s_sb, /* Pointer to the sup | |||
884 | } | 884 | } |
885 | 885 | ||
886 | /* Compare given item and item pointed to by the path. */ | 886 | /* Compare given item and item pointed to by the path. */ |
887 | int comp_items(const struct item_head *stored_ih, const struct path *p_s_path) | 887 | int comp_items(const struct item_head *stored_ih, const struct treepath *p_s_path) |
888 | { | 888 | { |
889 | struct buffer_head *p_s_bh; | 889 | struct buffer_head *p_s_bh; |
890 | struct item_head *ih; | 890 | struct item_head *ih; |
@@ -911,7 +911,7 @@ int comp_items(const struct item_head *stored_ih, const struct path *p_s_path) | |||
911 | #define block_in_use(bh) (buffer_locked(bh) || (held_by_others(bh))) | 911 | #define block_in_use(bh) (buffer_locked(bh) || (held_by_others(bh))) |
912 | 912 | ||
913 | // prepare for delete or cut of direct item | 913 | // prepare for delete or cut of direct item |
914 | static inline int prepare_for_direct_item(struct path *path, | 914 | static inline int prepare_for_direct_item(struct treepath *path, |
915 | struct item_head *le_ih, | 915 | struct item_head *le_ih, |
916 | struct inode *inode, | 916 | struct inode *inode, |
917 | loff_t new_file_length, int *cut_size) | 917 | loff_t new_file_length, int *cut_size) |
@@ -952,7 +952,7 @@ static inline int prepare_for_direct_item(struct path *path, | |||
952 | return M_CUT; /* Cut from this item. */ | 952 | return M_CUT; /* Cut from this item. */ |
953 | } | 953 | } |
954 | 954 | ||
955 | static inline int prepare_for_direntry_item(struct path *path, | 955 | static inline int prepare_for_direntry_item(struct treepath *path, |
956 | struct item_head *le_ih, | 956 | struct item_head *le_ih, |
957 | struct inode *inode, | 957 | struct inode *inode, |
958 | loff_t new_file_length, | 958 | loff_t new_file_length, |
@@ -987,7 +987,7 @@ static inline int prepare_for_direntry_item(struct path *path, | |||
987 | In case of file truncate calculate whether this item must be deleted/truncated or last | 987 | In case of file truncate calculate whether this item must be deleted/truncated or last |
988 | unformatted node of this item will be converted to a direct item. | 988 | unformatted node of this item will be converted to a direct item. |
989 | This function returns a determination of what balance mode the calling function should employ. */ | 989 | This function returns a determination of what balance mode the calling function should employ. */ |
990 | static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *p_s_path, const struct cpu_key *p_s_item_key, int *p_n_removed, /* Number of unformatted nodes which were removed | 990 | static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, struct inode *inode, struct treepath *p_s_path, const struct cpu_key *p_s_item_key, int *p_n_removed, /* Number of unformatted nodes which were removed |
991 | from end of the file. */ | 991 | from end of the file. */ |
992 | int *p_n_cut_size, unsigned long long n_new_file_length /* MAX_KEY_OFFSET in case of delete. */ | 992 | int *p_n_cut_size, unsigned long long n_new_file_length /* MAX_KEY_OFFSET in case of delete. */ |
993 | ) | 993 | ) |
@@ -1125,7 +1125,7 @@ static int calc_deleted_bytes_number(struct tree_balance *p_s_tb, char c_mode) | |||
1125 | static void init_tb_struct(struct reiserfs_transaction_handle *th, | 1125 | static void init_tb_struct(struct reiserfs_transaction_handle *th, |
1126 | struct tree_balance *p_s_tb, | 1126 | struct tree_balance *p_s_tb, |
1127 | struct super_block *p_s_sb, | 1127 | struct super_block *p_s_sb, |
1128 | struct path *p_s_path, int n_size) | 1128 | struct treepath *p_s_path, int n_size) |
1129 | { | 1129 | { |
1130 | 1130 | ||
1131 | BUG_ON(!th->t_trans_id); | 1131 | BUG_ON(!th->t_trans_id); |
@@ -1176,7 +1176,7 @@ char head2type(struct item_head *ih) | |||
1176 | #endif | 1176 | #endif |
1177 | 1177 | ||
1178 | /* Delete object item. */ | 1178 | /* Delete object item. */ |
1179 | int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct path *p_s_path, /* Path to the deleted item. */ | 1179 | int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct treepath *p_s_path, /* Path to the deleted item. */ |
1180 | const struct cpu_key *p_s_item_key, /* Key to search for the deleted item. */ | 1180 | const struct cpu_key *p_s_item_key, /* Key to search for the deleted item. */ |
1181 | struct inode *p_s_inode, /* inode is here just to update i_blocks and quotas */ | 1181 | struct inode *p_s_inode, /* inode is here just to update i_blocks and quotas */ |
1182 | struct buffer_head *p_s_un_bh) | 1182 | struct buffer_head *p_s_un_bh) |
@@ -1459,7 +1459,7 @@ static void unmap_buffers(struct page *page, loff_t pos) | |||
1459 | bh = next; | 1459 | bh = next; |
1460 | } while (bh != head); | 1460 | } while (bh != head); |
1461 | if (PAGE_SIZE == bh->b_size) { | 1461 | if (PAGE_SIZE == bh->b_size) { |
1462 | clear_page_dirty(page); | 1462 | cancel_dirty_page(page, PAGE_CACHE_SIZE); |
1463 | } | 1463 | } |
1464 | } | 1464 | } |
1465 | } | 1465 | } |
@@ -1468,7 +1468,7 @@ static void unmap_buffers(struct page *page, loff_t pos) | |||
1468 | static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th, | 1468 | static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th, |
1469 | struct inode *p_s_inode, | 1469 | struct inode *p_s_inode, |
1470 | struct page *page, | 1470 | struct page *page, |
1471 | struct path *p_s_path, | 1471 | struct treepath *p_s_path, |
1472 | const struct cpu_key *p_s_item_key, | 1472 | const struct cpu_key *p_s_item_key, |
1473 | loff_t n_new_file_size, char *p_c_mode) | 1473 | loff_t n_new_file_size, char *p_c_mode) |
1474 | { | 1474 | { |
@@ -1503,7 +1503,7 @@ static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th, | |||
1503 | pointer being converted. Therefore we have to delete inserted | 1503 | pointer being converted. Therefore we have to delete inserted |
1504 | direct item(s) */ | 1504 | direct item(s) */ |
1505 | static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th, | 1505 | static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th, |
1506 | struct inode *inode, struct path *path) | 1506 | struct inode *inode, struct treepath *path) |
1507 | { | 1507 | { |
1508 | struct cpu_key tail_key; | 1508 | struct cpu_key tail_key; |
1509 | int tail_len; | 1509 | int tail_len; |
@@ -1545,7 +1545,7 @@ static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th, | |||
1545 | 1545 | ||
1546 | /* (Truncate or cut entry) or delete object item. Returns < 0 on failure */ | 1546 | /* (Truncate or cut entry) or delete object item. Returns < 0 on failure */ |
1547 | int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, | 1547 | int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, |
1548 | struct path *p_s_path, | 1548 | struct treepath *p_s_path, |
1549 | struct cpu_key *p_s_item_key, | 1549 | struct cpu_key *p_s_item_key, |
1550 | struct inode *p_s_inode, | 1550 | struct inode *p_s_inode, |
1551 | struct page *page, loff_t n_new_file_size) | 1551 | struct page *page, loff_t n_new_file_size) |
@@ -1920,7 +1920,7 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p | |||
1920 | 1920 | ||
1921 | #ifdef CONFIG_REISERFS_CHECK | 1921 | #ifdef CONFIG_REISERFS_CHECK |
1922 | // this makes sure, that we __append__, not overwrite or add holes | 1922 | // this makes sure, that we __append__, not overwrite or add holes |
1923 | static void check_research_for_paste(struct path *path, | 1923 | static void check_research_for_paste(struct treepath *path, |
1924 | const struct cpu_key *p_s_key) | 1924 | const struct cpu_key *p_s_key) |
1925 | { | 1925 | { |
1926 | struct item_head *found_ih = get_ih(path); | 1926 | struct item_head *found_ih = get_ih(path); |
@@ -1954,7 +1954,7 @@ static void check_research_for_paste(struct path *path, | |||
1954 | #endif /* config reiserfs check */ | 1954 | #endif /* config reiserfs check */ |
1955 | 1955 | ||
1956 | /* Paste bytes to the existing item. Returns bytes number pasted into the item. */ | 1956 | /* Paste bytes to the existing item. Returns bytes number pasted into the item. */ |
1957 | int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct path *p_s_search_path, /* Path to the pasted item. */ | 1957 | int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct treepath *p_s_search_path, /* Path to the pasted item. */ |
1958 | const struct cpu_key *p_s_key, /* Key to search for the needed item. */ | 1958 | const struct cpu_key *p_s_key, /* Key to search for the needed item. */ |
1959 | struct inode *inode, /* Inode item belongs to */ | 1959 | struct inode *inode, /* Inode item belongs to */ |
1960 | const char *p_c_body, /* Pointer to the bytes to paste. */ | 1960 | const char *p_c_body, /* Pointer to the bytes to paste. */ |
@@ -2036,7 +2036,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct path | |||
2036 | } | 2036 | } |
2037 | 2037 | ||
2038 | /* Insert new item into the buffer at the path. */ | 2038 | /* Insert new item into the buffer at the path. */ |
2039 | int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct path *p_s_path, /* Path to the inserteded item. */ | 2039 | int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct treepath *p_s_path, /* Path to the inserteded item. */ |
2040 | const struct cpu_key *key, struct item_head *p_s_ih, /* Pointer to the item header to insert. */ | 2040 | const struct cpu_key *key, struct item_head *p_s_ih, /* Pointer to the item header to insert. */ |
2041 | struct inode *inode, const char *p_c_body) | 2041 | struct inode *inode, const char *p_c_body) |
2042 | { /* Pointer to the bytes to insert. */ | 2042 | { /* Pointer to the bytes to insert. */ |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 17249994110f..58ad4551a7c1 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/buffer_head.h> | 24 | #include <linux/buffer_head.h> |
25 | #include <linux/vfs.h> | 25 | #include <linux/vfs.h> |
26 | #include <linux/namespace.h> | 26 | #include <linux/mnt_namespace.h> |
27 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
28 | #include <linux/namei.h> | 28 | #include <linux/namei.h> |
29 | #include <linux/quotaops.h> | 29 | #include <linux/quotaops.h> |
@@ -490,13 +490,13 @@ static void reiserfs_put_super(struct super_block *s) | |||
490 | return; | 490 | return; |
491 | } | 491 | } |
492 | 492 | ||
493 | static kmem_cache_t *reiserfs_inode_cachep; | 493 | static struct kmem_cache *reiserfs_inode_cachep; |
494 | 494 | ||
495 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) | 495 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) |
496 | { | 496 | { |
497 | struct reiserfs_inode_info *ei; | 497 | struct reiserfs_inode_info *ei; |
498 | ei = (struct reiserfs_inode_info *) | 498 | ei = (struct reiserfs_inode_info *) |
499 | kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL); | 499 | kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); |
500 | if (!ei) | 500 | if (!ei) |
501 | return NULL; | 501 | return NULL; |
502 | return &ei->vfs_inode; | 502 | return &ei->vfs_inode; |
@@ -507,7 +507,7 @@ static void reiserfs_destroy_inode(struct inode *inode) | |||
507 | kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); | 507 | kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); |
508 | } | 508 | } |
509 | 509 | ||
510 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 510 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
511 | { | 511 | { |
512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; | 512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; |
513 | 513 | ||
@@ -1549,13 +1549,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1549 | struct reiserfs_sb_info *sbi; | 1549 | struct reiserfs_sb_info *sbi; |
1550 | int errval = -EINVAL; | 1550 | int errval = -EINVAL; |
1551 | 1551 | ||
1552 | sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); | 1552 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); |
1553 | if (!sbi) { | 1553 | if (!sbi) { |
1554 | errval = -ENOMEM; | 1554 | errval = -ENOMEM; |
1555 | goto error; | 1555 | goto error; |
1556 | } | 1556 | } |
1557 | s->s_fs_info = sbi; | 1557 | s->s_fs_info = sbi; |
1558 | memset(sbi, 0, sizeof(struct reiserfs_sb_info)); | ||
1559 | /* Set default values for options: non-aggressive tails, RO on errors */ | 1558 | /* Set default values for options: non-aggressive tails, RO on errors */ |
1560 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); | 1559 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); |
1561 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); | 1560 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); |
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c index 36f108fc1cf5..f8121a1147e8 100644 --- a/fs/reiserfs/tail_conversion.c +++ b/fs/reiserfs/tail_conversion.c | |||
@@ -15,7 +15,7 @@ | |||
15 | /* path points to first direct item of the file regarless of how many of | 15 | /* path points to first direct item of the file regarless of how many of |
16 | them are there */ | 16 | them are there */ |
17 | int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, | 17 | int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, |
18 | struct path *path, struct buffer_head *unbh, | 18 | struct treepath *path, struct buffer_head *unbh, |
19 | loff_t tail_offset) | 19 | loff_t tail_offset) |
20 | { | 20 | { |
21 | struct super_block *sb = inode->i_sb; | 21 | struct super_block *sb = inode->i_sb; |
@@ -171,7 +171,7 @@ void reiserfs_unmap_buffer(struct buffer_head *bh) | |||
171 | what we expect from it (number of cut bytes). But when tail remains | 171 | what we expect from it (number of cut bytes). But when tail remains |
172 | in the unformatted node, we set mode to SKIP_BALANCING and unlock | 172 | in the unformatted node, we set mode to SKIP_BALANCING and unlock |
173 | inode */ | 173 | inode */ |
174 | int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_inode, struct page *page, struct path *p_s_path, /* path to the indirect item. */ | 174 | int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_inode, struct page *page, struct treepath *p_s_path, /* path to the indirect item. */ |
175 | const struct cpu_key *p_s_item_key, /* Key to look for unformatted node pointer to be cut. */ | 175 | const struct cpu_key *p_s_item_key, /* Key to look for unformatted node pointer to be cut. */ |
176 | loff_t n_new_file_size, /* New file size. */ | 176 | loff_t n_new_file_size, /* New file size. */ |
177 | char *p_c_mode) | 177 | char *p_c_mode) |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 7bdb0ed443e1..f01389fd162e 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <linux/reiserfs_xattr.h> | 41 | #include <linux/reiserfs_xattr.h> |
42 | #include <linux/reiserfs_acl.h> | 42 | #include <linux/reiserfs_acl.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/checksum.h> | 44 | #include <net/checksum.h> |
45 | #include <linux/smp_lock.h> | 45 | #include <linux/smp_lock.h> |
46 | #include <linux/stat.h> | 46 | #include <linux/stat.h> |
47 | #include <asm/semaphore.h> | 47 | #include <asm/semaphore.h> |
@@ -274,7 +274,7 @@ static struct file *open_xa_file(const struct inode *inode, const char *name, | |||
274 | */ | 274 | */ |
275 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | 275 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) |
276 | { | 276 | { |
277 | struct inode *inode = filp->f_dentry->d_inode; | 277 | struct inode *inode = filp->f_path.dentry->d_inode; |
278 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 278 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
279 | INITIALIZE_PATH(path_to_entry); | 279 | INITIALIZE_PATH(path_to_entry); |
280 | struct buffer_head *bh; | 280 | struct buffer_head *bh; |
@@ -420,7 +420,7 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
420 | static | 420 | static |
421 | int xattr_readdir(struct file *file, filldir_t filler, void *buf) | 421 | int xattr_readdir(struct file *file, filldir_t filler, void *buf) |
422 | { | 422 | { |
423 | struct inode *inode = file->f_dentry->d_inode; | 423 | struct inode *inode = file->f_path.dentry->d_inode; |
424 | int res = -ENOTDIR; | 424 | int res = -ENOTDIR; |
425 | if (!file->f_op || !file->f_op->readdir) | 425 | if (!file->f_op || !file->f_op->readdir) |
426 | goto out; | 426 | goto out; |
@@ -508,7 +508,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
508 | goto out; | 508 | goto out; |
509 | } | 509 | } |
510 | 510 | ||
511 | xinode = fp->f_dentry->d_inode; | 511 | xinode = fp->f_path.dentry->d_inode; |
512 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 512 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
513 | 513 | ||
514 | /* we need to copy it off.. */ | 514 | /* we need to copy it off.. */ |
@@ -527,7 +527,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
527 | newattrs.ia_size = buffer_size; | 527 | newattrs.ia_size = buffer_size; |
528 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 528 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
529 | mutex_lock(&xinode->i_mutex); | 529 | mutex_lock(&xinode->i_mutex); |
530 | err = notify_change(fp->f_dentry, &newattrs); | 530 | err = notify_change(fp->f_path.dentry, &newattrs); |
531 | if (err) | 531 | if (err) |
532 | goto out_filp; | 532 | goto out_filp; |
533 | 533 | ||
@@ -626,7 +626,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | |||
626 | goto out; | 626 | goto out; |
627 | } | 627 | } |
628 | 628 | ||
629 | xinode = fp->f_dentry->d_inode; | 629 | xinode = fp->f_path.dentry->d_inode; |
630 | isize = xinode->i_size; | 630 | isize = xinode->i_size; |
631 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 631 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
632 | 632 | ||
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 97ae1b92bc47..5296a29cc5eb 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -135,7 +135,7 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) | |||
135 | int n; | 135 | int n; |
136 | 136 | ||
137 | *size = reiserfs_acl_size(acl->a_count); | 137 | *size = reiserfs_acl_size(acl->a_count); |
138 | ext_acl = (reiserfs_acl_header *) kmalloc(sizeof(reiserfs_acl_header) + | 138 | ext_acl = kmalloc(sizeof(reiserfs_acl_header) + |
139 | acl->a_count * | 139 | acl->a_count * |
140 | sizeof(reiserfs_acl_entry), | 140 | sizeof(reiserfs_acl_entry), |
141 | GFP_NOFS); | 141 | GFP_NOFS); |
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index ddcd9e1ef282..d3e243a6f609 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c | |||
@@ -276,7 +276,7 @@ static unsigned char romfs_dtype_table[] = { | |||
276 | static int | 276 | static int |
277 | romfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 277 | romfs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
278 | { | 278 | { |
279 | struct inode *i = filp->f_dentry->d_inode; | 279 | struct inode *i = filp->f_path.dentry->d_inode; |
280 | struct romfs_inode ri; | 280 | struct romfs_inode ri; |
281 | unsigned long offset, maxoff; | 281 | unsigned long offset, maxoff; |
282 | int j, ino, nextfh; | 282 | int j, ino, nextfh; |
@@ -550,12 +550,12 @@ romfs_read_inode(struct inode *i) | |||
550 | } | 550 | } |
551 | } | 551 | } |
552 | 552 | ||
553 | static kmem_cache_t * romfs_inode_cachep; | 553 | static struct kmem_cache * romfs_inode_cachep; |
554 | 554 | ||
555 | static struct inode *romfs_alloc_inode(struct super_block *sb) | 555 | static struct inode *romfs_alloc_inode(struct super_block *sb) |
556 | { | 556 | { |
557 | struct romfs_inode_info *ei; | 557 | struct romfs_inode_info *ei; |
558 | ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, SLAB_KERNEL); | 558 | ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL); |
559 | if (!ei) | 559 | if (!ei) |
560 | return NULL; | 560 | return NULL; |
561 | return &ei->vfs_inode; | 561 | return &ei->vfs_inode; |
@@ -566,7 +566,7 @@ static void romfs_destroy_inode(struct inode *inode) | |||
566 | kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); | 566 | kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); |
567 | } | 567 | } |
568 | 568 | ||
569 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 569 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
570 | { | 570 | { |
571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; | 571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; |
572 | 572 | ||
diff --git a/fs/select.c b/fs/select.c index dcbc1112b7ec..fe0893afd931 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -311,7 +311,7 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
311 | { | 311 | { |
312 | fd_set_bits fds; | 312 | fd_set_bits fds; |
313 | void *bits; | 313 | void *bits; |
314 | int ret, max_fdset; | 314 | int ret, max_fds; |
315 | unsigned int size; | 315 | unsigned int size; |
316 | struct fdtable *fdt; | 316 | struct fdtable *fdt; |
317 | /* Allocate small arguments on the stack to save memory and be faster */ | 317 | /* Allocate small arguments on the stack to save memory and be faster */ |
@@ -321,13 +321,13 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
321 | if (n < 0) | 321 | if (n < 0) |
322 | goto out_nofds; | 322 | goto out_nofds; |
323 | 323 | ||
324 | /* max_fdset can increase, so grab it once to avoid race */ | 324 | /* max_fds can increase, so grab it once to avoid race */ |
325 | rcu_read_lock(); | 325 | rcu_read_lock(); |
326 | fdt = files_fdtable(current->files); | 326 | fdt = files_fdtable(current->files); |
327 | max_fdset = fdt->max_fdset; | 327 | max_fds = fdt->max_fds; |
328 | rcu_read_unlock(); | 328 | rcu_read_unlock(); |
329 | if (n > max_fdset) | 329 | if (n > max_fds) |
330 | n = max_fdset; | 330 | n = max_fds; |
331 | 331 | ||
332 | /* | 332 | /* |
333 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), | 333 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 555b9ac04c25..0ac22af7afe5 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * ERR_PTR(error). In the end of sequence they return %NULL. ->show() | 26 | * ERR_PTR(error). In the end of sequence they return %NULL. ->show() |
27 | * returns 0 in case of success and negative number in case of error. | 27 | * returns 0 in case of success and negative number in case of error. |
28 | */ | 28 | */ |
29 | int seq_open(struct file *file, struct seq_operations *op) | 29 | int seq_open(struct file *file, const struct seq_operations *op) |
30 | { | 30 | { |
31 | struct seq_file *p = file->private_data; | 31 | struct seq_file *p = file->private_data; |
32 | 32 | ||
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(seq_lseek); | |||
269 | /** | 269 | /** |
270 | * seq_release - free the structures associated with sequential file. | 270 | * seq_release - free the structures associated with sequential file. |
271 | * @file: file in question | 271 | * @file: file in question |
272 | * @inode: file->f_dentry->d_inode | 272 | * @inode: file->f_path.dentry->d_inode |
273 | * | 273 | * |
274 | * Frees the structures associated with sequential file; can be used | 274 | * Frees the structures associated with sequential file; can be used |
275 | * as ->f_op->release() if you don't have private data to destroy. | 275 | * as ->f_op->release() if you don't have private data to destroy. |
@@ -408,7 +408,7 @@ EXPORT_SYMBOL(single_open); | |||
408 | 408 | ||
409 | int single_release(struct inode *inode, struct file *file) | 409 | int single_release(struct inode *inode, struct file *file) |
410 | { | 410 | { |
411 | struct seq_operations *op = ((struct seq_file *)file->private_data)->op; | 411 | const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; |
412 | int res = seq_release(inode, file); | 412 | int res = seq_release(inode, file); |
413 | kfree(op); | 413 | kfree(op); |
414 | return res; | 414 | return res; |
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c index 74b86d9725a6..8182f0542a21 100644 --- a/fs/smbfs/cache.c +++ b/fs/smbfs/cache.c | |||
@@ -125,7 +125,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | |||
125 | struct smb_cache_control *ctrl, struct qstr *qname, | 125 | struct smb_cache_control *ctrl, struct qstr *qname, |
126 | struct smb_fattr *entry) | 126 | struct smb_fattr *entry) |
127 | { | 127 | { |
128 | struct dentry *newdent, *dentry = filp->f_dentry; | 128 | struct dentry *newdent, *dentry = filp->f_path.dentry; |
129 | struct inode *newino, *inode = dentry->d_inode; | 129 | struct inode *newino, *inode = dentry->d_inode; |
130 | struct smb_cache_control ctl = *ctrl; | 130 | struct smb_cache_control ctl = *ctrl; |
131 | int valid = 0; | 131 | int valid = 0; |
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 70d9c5a37f5a..b1e58d1ac9ca 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c | |||
@@ -78,7 +78,7 @@ struct inode_operations smb_dir_inode_operations_unix = | |||
78 | static int | 78 | static int |
79 | smb_readdir(struct file *filp, void *dirent, filldir_t filldir) | 79 | smb_readdir(struct file *filp, void *dirent, filldir_t filldir) |
80 | { | 80 | { |
81 | struct dentry *dentry = filp->f_dentry; | 81 | struct dentry *dentry = filp->f_path.dentry; |
82 | struct inode *dir = dentry->d_inode; | 82 | struct inode *dir = dentry->d_inode; |
83 | struct smb_sb_info *server = server_from_dentry(dentry); | 83 | struct smb_sb_info *server = server_from_dentry(dentry); |
84 | union smb_dir_cache *cache = NULL; | 84 | union smb_dir_cache *cache = NULL; |
@@ -238,12 +238,12 @@ out: | |||
238 | static int | 238 | static int |
239 | smb_dir_open(struct inode *dir, struct file *file) | 239 | smb_dir_open(struct inode *dir, struct file *file) |
240 | { | 240 | { |
241 | struct dentry *dentry = file->f_dentry; | 241 | struct dentry *dentry = file->f_path.dentry; |
242 | struct smb_sb_info *server; | 242 | struct smb_sb_info *server; |
243 | int error = 0; | 243 | int error = 0; |
244 | 244 | ||
245 | VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, | 245 | VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, |
246 | file->f_dentry->d_name.name); | 246 | file->f_path.dentry->d_name.name); |
247 | 247 | ||
248 | /* | 248 | /* |
249 | * Directory timestamps in the core protocol aren't updated | 249 | * Directory timestamps in the core protocol aren't updated |
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 50784d13c87b..e50533a79517 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c | |||
@@ -102,7 +102,7 @@ static int | |||
102 | smb_readpage(struct file *file, struct page *page) | 102 | smb_readpage(struct file *file, struct page *page) |
103 | { | 103 | { |
104 | int error; | 104 | int error; |
105 | struct dentry *dentry = file->f_dentry; | 105 | struct dentry *dentry = file->f_path.dentry; |
106 | 106 | ||
107 | page_cache_get(page); | 107 | page_cache_get(page); |
108 | error = smb_readpage_sync(dentry, page); | 108 | error = smb_readpage_sync(dentry, page); |
@@ -205,7 +205,7 @@ static int | |||
205 | smb_updatepage(struct file *file, struct page *page, unsigned long offset, | 205 | smb_updatepage(struct file *file, struct page *page, unsigned long offset, |
206 | unsigned int count) | 206 | unsigned int count) |
207 | { | 207 | { |
208 | struct dentry *dentry = file->f_dentry; | 208 | struct dentry *dentry = file->f_path.dentry; |
209 | 209 | ||
210 | DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count, | 210 | DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count, |
211 | ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset); | 211 | ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset); |
@@ -218,7 +218,7 @@ smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
218 | unsigned long nr_segs, loff_t pos) | 218 | unsigned long nr_segs, loff_t pos) |
219 | { | 219 | { |
220 | struct file * file = iocb->ki_filp; | 220 | struct file * file = iocb->ki_filp; |
221 | struct dentry * dentry = file->f_dentry; | 221 | struct dentry * dentry = file->f_path.dentry; |
222 | ssize_t status; | 222 | ssize_t status; |
223 | 223 | ||
224 | VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), | 224 | VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), |
@@ -243,7 +243,7 @@ out: | |||
243 | static int | 243 | static int |
244 | smb_file_mmap(struct file * file, struct vm_area_struct * vma) | 244 | smb_file_mmap(struct file * file, struct vm_area_struct * vma) |
245 | { | 245 | { |
246 | struct dentry * dentry = file->f_dentry; | 246 | struct dentry * dentry = file->f_path.dentry; |
247 | int status; | 247 | int status; |
248 | 248 | ||
249 | VERBOSE("file %s/%s, address %lu - %lu\n", | 249 | VERBOSE("file %s/%s, address %lu - %lu\n", |
@@ -264,7 +264,7 @@ static ssize_t | |||
264 | smb_file_sendfile(struct file *file, loff_t *ppos, | 264 | smb_file_sendfile(struct file *file, loff_t *ppos, |
265 | size_t count, read_actor_t actor, void *target) | 265 | size_t count, read_actor_t actor, void *target) |
266 | { | 266 | { |
267 | struct dentry *dentry = file->f_dentry; | 267 | struct dentry *dentry = file->f_path.dentry; |
268 | ssize_t status; | 268 | ssize_t status; |
269 | 269 | ||
270 | VERBOSE("file %s/%s, pos=%Ld, count=%d\n", | 270 | VERBOSE("file %s/%s, pos=%Ld, count=%d\n", |
@@ -323,7 +323,7 @@ smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
323 | unsigned long nr_segs, loff_t pos) | 323 | unsigned long nr_segs, loff_t pos) |
324 | { | 324 | { |
325 | struct file * file = iocb->ki_filp; | 325 | struct file * file = iocb->ki_filp; |
326 | struct dentry * dentry = file->f_dentry; | 326 | struct dentry * dentry = file->f_path.dentry; |
327 | ssize_t result; | 327 | ssize_t result; |
328 | 328 | ||
329 | VERBOSE("file %s/%s, count=%lu@%lu\n", | 329 | VERBOSE("file %s/%s, count=%lu@%lu\n", |
@@ -355,7 +355,7 @@ static int | |||
355 | smb_file_open(struct inode *inode, struct file * file) | 355 | smb_file_open(struct inode *inode, struct file * file) |
356 | { | 356 | { |
357 | int result; | 357 | int result; |
358 | struct dentry *dentry = file->f_dentry; | 358 | struct dentry *dentry = file->f_path.dentry; |
359 | int smb_mode = (file->f_mode & O_ACCMODE) - 1; | 359 | int smb_mode = (file->f_mode & O_ACCMODE) - 1; |
360 | 360 | ||
361 | lock_kernel(); | 361 | lock_kernel(); |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 2c122ee83adb..84dfe3f3482e 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -50,12 +50,12 @@ static void smb_put_super(struct super_block *); | |||
50 | static int smb_statfs(struct dentry *, struct kstatfs *); | 50 | static int smb_statfs(struct dentry *, struct kstatfs *); |
51 | static int smb_show_options(struct seq_file *, struct vfsmount *); | 51 | static int smb_show_options(struct seq_file *, struct vfsmount *); |
52 | 52 | ||
53 | static kmem_cache_t *smb_inode_cachep; | 53 | static struct kmem_cache *smb_inode_cachep; |
54 | 54 | ||
55 | static struct inode *smb_alloc_inode(struct super_block *sb) | 55 | static struct inode *smb_alloc_inode(struct super_block *sb) |
56 | { | 56 | { |
57 | struct smb_inode_info *ei; | 57 | struct smb_inode_info *ei; |
58 | ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL); | 58 | ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL); |
59 | if (!ei) | 59 | if (!ei) |
60 | return NULL; | 60 | return NULL; |
61 | return &ei->vfs_inode; | 61 | return &ei->vfs_inode; |
@@ -66,7 +66,7 @@ static void smb_destroy_inode(struct inode *inode) | |||
66 | kmem_cache_free(smb_inode_cachep, SMB_I(inode)); | 66 | kmem_cache_free(smb_inode_cachep, SMB_I(inode)); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 69 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
70 | { | 70 | { |
71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; | 71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; |
72 | unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; | 72 | unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; |
@@ -482,12 +482,13 @@ smb_put_super(struct super_block *sb) | |||
482 | smb_close_socket(server); | 482 | smb_close_socket(server); |
483 | 483 | ||
484 | if (server->conn_pid) | 484 | if (server->conn_pid) |
485 | kill_proc(server->conn_pid, SIGTERM, 1); | 485 | kill_pid(server->conn_pid, SIGTERM, 1); |
486 | 486 | ||
487 | kfree(server->ops); | 487 | kfree(server->ops); |
488 | smb_unload_nls(server); | 488 | smb_unload_nls(server); |
489 | sb->s_fs_info = NULL; | 489 | sb->s_fs_info = NULL; |
490 | smb_unlock_server(server); | 490 | smb_unlock_server(server); |
491 | put_pid(server->conn_pid); | ||
491 | kfree(server); | 492 | kfree(server); |
492 | } | 493 | } |
493 | 494 | ||
@@ -530,7 +531,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
530 | INIT_LIST_HEAD(&server->xmitq); | 531 | INIT_LIST_HEAD(&server->xmitq); |
531 | INIT_LIST_HEAD(&server->recvq); | 532 | INIT_LIST_HEAD(&server->recvq); |
532 | server->conn_error = 0; | 533 | server->conn_error = 0; |
533 | server->conn_pid = 0; | 534 | server->conn_pid = NULL; |
534 | server->state = CONN_INVALID; /* no connection yet */ | 535 | server->state = CONN_INVALID; /* no connection yet */ |
535 | server->generation = 0; | 536 | server->generation = 0; |
536 | 537 | ||
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index 40e174db9872..feac46050619 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c | |||
@@ -873,11 +873,11 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) | |||
873 | filp = fget(opt->fd); | 873 | filp = fget(opt->fd); |
874 | if (!filp) | 874 | if (!filp) |
875 | goto out; | 875 | goto out; |
876 | if (!smb_valid_socket(filp->f_dentry->d_inode)) | 876 | if (!smb_valid_socket(filp->f_path.dentry->d_inode)) |
877 | goto out_putf; | 877 | goto out_putf; |
878 | 878 | ||
879 | server->sock_file = filp; | 879 | server->sock_file = filp; |
880 | server->conn_pid = current->pid; | 880 | server->conn_pid = get_pid(task_pid(current)); |
881 | server->opt = *opt; | 881 | server->opt = *opt; |
882 | server->generation += 1; | 882 | server->generation += 1; |
883 | server->state = CONN_VALID; | 883 | server->state = CONN_VALID; |
@@ -898,7 +898,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) | |||
898 | /* | 898 | /* |
899 | * Store the server in sock user_data (Only used by sunrpc) | 899 | * Store the server in sock user_data (Only used by sunrpc) |
900 | */ | 900 | */ |
901 | sk = SOCKET_I(filp->f_dentry->d_inode)->sk; | 901 | sk = SOCKET_I(filp->f_path.dentry->d_inode)->sk; |
902 | sk->sk_user_data = server; | 902 | sk->sk_user_data = server; |
903 | 903 | ||
904 | /* chain into the data_ready callback */ | 904 | /* chain into the data_ready callback */ |
@@ -971,8 +971,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) | |||
971 | } | 971 | } |
972 | 972 | ||
973 | VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", | 973 | VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", |
974 | server->opt.protocol, server->opt.max_xmit, server->conn_pid, | 974 | server->opt.protocol, server->opt.max_xmit, |
975 | server->opt.capabilities); | 975 | pid_nr(server->conn_pid), server->opt.capabilities); |
976 | 976 | ||
977 | /* FIXME: this really should be done by smbmount. */ | 977 | /* FIXME: this really should be done by smbmount. */ |
978 | if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) { | 978 | if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) { |
@@ -1939,7 +1939,7 @@ static int | |||
1939 | smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, | 1939 | smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, |
1940 | struct smb_cache_control *ctl) | 1940 | struct smb_cache_control *ctl) |
1941 | { | 1941 | { |
1942 | struct dentry *dir = filp->f_dentry; | 1942 | struct dentry *dir = filp->f_path.dentry; |
1943 | struct smb_sb_info *server = server_from_dentry(dir); | 1943 | struct smb_sb_info *server = server_from_dentry(dir); |
1944 | struct qstr qname; | 1944 | struct qstr qname; |
1945 | struct smb_fattr fattr; | 1945 | struct smb_fattr fattr; |
@@ -2291,7 +2291,7 @@ static int | |||
2291 | smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, | 2291 | smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, |
2292 | struct smb_cache_control *ctl) | 2292 | struct smb_cache_control *ctl) |
2293 | { | 2293 | { |
2294 | struct dentry *dir = filp->f_dentry; | 2294 | struct dentry *dir = filp->f_path.dentry; |
2295 | struct smb_sb_info *server = server_from_dentry(dir); | 2295 | struct smb_sb_info *server = server_from_dentry(dir); |
2296 | struct qstr qname; | 2296 | struct qstr qname; |
2297 | struct smb_fattr fattr; | 2297 | struct smb_fattr fattr; |
@@ -2859,7 +2859,7 @@ static int | |||
2859 | smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir, | 2859 | smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir, |
2860 | struct smb_cache_control *ctl) | 2860 | struct smb_cache_control *ctl) |
2861 | { | 2861 | { |
2862 | struct smb_sb_info *server = server_from_dentry(filp->f_dentry); | 2862 | struct smb_sb_info *server = server_from_dentry(filp->f_path.dentry); |
2863 | 2863 | ||
2864 | if (smb_proc_ops_wait(server) < 0) | 2864 | if (smb_proc_ops_wait(server) < 0) |
2865 | return -EIO; | 2865 | return -EIO; |
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 0fb74697abc4..a4bcae8a9aff 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #define ROUND_UP(x) (((x)+3) & ~3) | 25 | #define ROUND_UP(x) (((x)+3) & ~3) |
26 | 26 | ||
27 | /* cache for request structures */ | 27 | /* cache for request structures */ |
28 | static kmem_cache_t *req_cachep; | 28 | static struct kmem_cache *req_cachep; |
29 | 29 | ||
30 | static int smb_request_send_req(struct smb_request *req); | 30 | static int smb_request_send_req(struct smb_request *req); |
31 | 31 | ||
@@ -61,7 +61,7 @@ static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server, | |||
61 | struct smb_request *req; | 61 | struct smb_request *req; |
62 | unsigned char *buf = NULL; | 62 | unsigned char *buf = NULL; |
63 | 63 | ||
64 | req = kmem_cache_alloc(req_cachep, SLAB_KERNEL); | 64 | req = kmem_cache_alloc(req_cachep, GFP_KERNEL); |
65 | VERBOSE("allocating request: %p\n", req); | 65 | VERBOSE("allocating request: %p\n", req); |
66 | if (!req) | 66 | if (!req) |
67 | goto out; | 67 | goto out; |
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c index e67540441288..89eaf31f1d46 100644 --- a/fs/smbfs/smbiod.c +++ b/fs/smbfs/smbiod.c | |||
@@ -152,7 +152,7 @@ int smbiod_retry(struct smb_sb_info *server) | |||
152 | { | 152 | { |
153 | struct list_head *head; | 153 | struct list_head *head; |
154 | struct smb_request *req; | 154 | struct smb_request *req; |
155 | pid_t pid = server->conn_pid; | 155 | struct pid *pid = get_pid(server->conn_pid); |
156 | int result = 0; | 156 | int result = 0; |
157 | 157 | ||
158 | VERBOSE("state: %d\n", server->state); | 158 | VERBOSE("state: %d\n", server->state); |
@@ -222,7 +222,7 @@ int smbiod_retry(struct smb_sb_info *server) | |||
222 | /* | 222 | /* |
223 | * Note: use the "priv" flag, as a user process may need to reconnect. | 223 | * Note: use the "priv" flag, as a user process may need to reconnect. |
224 | */ | 224 | */ |
225 | result = kill_proc(pid, SIGUSR1, 1); | 225 | result = kill_pid(pid, SIGUSR1, 1); |
226 | if (result) { | 226 | if (result) { |
227 | /* FIXME: this is most likely fatal, umount? */ | 227 | /* FIXME: this is most likely fatal, umount? */ |
228 | printk(KERN_ERR "smb_retry: signal failed [%d]\n", result); | 228 | printk(KERN_ERR "smb_retry: signal failed [%d]\n", result); |
@@ -233,6 +233,7 @@ int smbiod_retry(struct smb_sb_info *server) | |||
233 | /* FIXME: The retried requests should perhaps get a "time boost". */ | 233 | /* FIXME: The retried requests should perhaps get a "time boost". */ |
234 | 234 | ||
235 | out: | 235 | out: |
236 | put_pid(pid); | ||
236 | return result; | 237 | return result; |
237 | } | 238 | } |
238 | 239 | ||
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 6815b1b12b68..92ea6b2367d7 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c | |||
@@ -82,10 +82,10 @@ server_sock(struct smb_sb_info *server) | |||
82 | if (server && (file = server->sock_file)) | 82 | if (server && (file = server->sock_file)) |
83 | { | 83 | { |
84 | #ifdef SMBFS_PARANOIA | 84 | #ifdef SMBFS_PARANOIA |
85 | if (!smb_valid_socket(file->f_dentry->d_inode)) | 85 | if (!smb_valid_socket(file->f_path.dentry->d_inode)) |
86 | PARANOIA("bad socket!\n"); | 86 | PARANOIA("bad socket!\n"); |
87 | #endif | 87 | #endif |
88 | return SOCKET_I(file->f_dentry->d_inode); | 88 | return SOCKET_I(file->f_path.dentry->d_inode); |
89 | } | 89 | } |
90 | return NULL; | 90 | return NULL; |
91 | } | 91 | } |
diff --git a/fs/splice.c b/fs/splice.c index da74583a00ee..2fca6ebf4cc2 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -42,7 +42,7 @@ struct splice_pipe_desc { | |||
42 | struct partial_page *partial; /* pages[] may not be contig */ | 42 | struct partial_page *partial; /* pages[] may not be contig */ |
43 | int nr_pages; /* number of pages in map */ | 43 | int nr_pages; /* number of pages in map */ |
44 | unsigned int flags; /* splice flags */ | 44 | unsigned int flags; /* splice flags */ |
45 | struct pipe_buf_operations *ops;/* ops associated with output pipe */ | 45 | const struct pipe_buf_operations *ops;/* ops associated with output pipe */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | /* | 48 | /* |
@@ -139,7 +139,7 @@ error: | |||
139 | return err; | 139 | return err; |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { | 142 | static const struct pipe_buf_operations page_cache_pipe_buf_ops = { |
143 | .can_merge = 0, | 143 | .can_merge = 0, |
144 | .map = generic_pipe_buf_map, | 144 | .map = generic_pipe_buf_map, |
145 | .unmap = generic_pipe_buf_unmap, | 145 | .unmap = generic_pipe_buf_unmap, |
@@ -159,7 +159,7 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
159 | return generic_pipe_buf_steal(pipe, buf); | 159 | return generic_pipe_buf_steal(pipe, buf); |
160 | } | 160 | } |
161 | 161 | ||
162 | static struct pipe_buf_operations user_page_pipe_buf_ops = { | 162 | static const struct pipe_buf_operations user_page_pipe_buf_ops = { |
163 | .can_merge = 0, | 163 | .can_merge = 0, |
164 | .map = generic_pipe_buf_map, | 164 | .map = generic_pipe_buf_map, |
165 | .unmap = generic_pipe_buf_unmap, | 165 | .unmap = generic_pipe_buf_unmap, |
@@ -724,7 +724,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, | |||
724 | for (;;) { | 724 | for (;;) { |
725 | if (pipe->nrbufs) { | 725 | if (pipe->nrbufs) { |
726 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | 726 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; |
727 | struct pipe_buf_operations *ops = buf->ops; | 727 | const struct pipe_buf_operations *ops = buf->ops; |
728 | 728 | ||
729 | sd.len = buf->len; | 729 | sd.len = buf->len; |
730 | if (sd.len > sd.total_len) | 730 | if (sd.len > sd.total_len) |
@@ -844,7 +844,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, | |||
844 | ssize_t ret; | 844 | ssize_t ret; |
845 | int err; | 845 | int err; |
846 | 846 | ||
847 | err = remove_suid(out->f_dentry); | 847 | err = remove_suid(out->f_path.dentry); |
848 | if (unlikely(err)) | 848 | if (unlikely(err)) |
849 | return err; | 849 | return err; |
850 | 850 | ||
@@ -890,10 +890,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
890 | ssize_t ret; | 890 | ssize_t ret; |
891 | int err; | 891 | int err; |
892 | 892 | ||
893 | err = should_remove_suid(out->f_dentry); | 893 | err = should_remove_suid(out->f_path.dentry); |
894 | if (unlikely(err)) { | 894 | if (unlikely(err)) { |
895 | mutex_lock(&inode->i_mutex); | 895 | mutex_lock(&inode->i_mutex); |
896 | err = __remove_suid(out->f_dentry, err); | 896 | err = __remove_suid(out->f_path.dentry, err); |
897 | mutex_unlock(&inode->i_mutex); | 897 | mutex_unlock(&inode->i_mutex); |
898 | if (err) | 898 | if (err) |
899 | return err; | 899 | return err; |
@@ -1008,7 +1008,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
1008 | * randomly drop data for eg socket -> socket splicing. Use the | 1008 | * randomly drop data for eg socket -> socket splicing. Use the |
1009 | * piped splicing for that! | 1009 | * piped splicing for that! |
1010 | */ | 1010 | */ |
1011 | i_mode = in->f_dentry->d_inode->i_mode; | 1011 | i_mode = in->f_path.dentry->d_inode->i_mode; |
1012 | if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode))) | 1012 | if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode))) |
1013 | return -EINVAL; | 1013 | return -EINVAL; |
1014 | 1014 | ||
@@ -1132,7 +1132,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1132 | loff_t offset, *off; | 1132 | loff_t offset, *off; |
1133 | long ret; | 1133 | long ret; |
1134 | 1134 | ||
1135 | pipe = pipe_info(in->f_dentry->d_inode); | 1135 | pipe = pipe_info(in->f_path.dentry->d_inode); |
1136 | if (pipe) { | 1136 | if (pipe) { |
1137 | if (off_in) | 1137 | if (off_in) |
1138 | return -ESPIPE; | 1138 | return -ESPIPE; |
@@ -1153,7 +1153,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1153 | return ret; | 1153 | return ret; |
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | pipe = pipe_info(out->f_dentry->d_inode); | 1156 | pipe = pipe_info(out->f_path.dentry->d_inode); |
1157 | if (pipe) { | 1157 | if (pipe) { |
1158 | if (off_out) | 1158 | if (off_out) |
1159 | return -ESPIPE; | 1159 | return -ESPIPE; |
@@ -1321,7 +1321,7 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, | |||
1321 | .ops = &user_page_pipe_buf_ops, | 1321 | .ops = &user_page_pipe_buf_ops, |
1322 | }; | 1322 | }; |
1323 | 1323 | ||
1324 | pipe = pipe_info(file->f_dentry->d_inode); | 1324 | pipe = pipe_info(file->f_path.dentry->d_inode); |
1325 | if (!pipe) | 1325 | if (!pipe) |
1326 | return -EBADF; | 1326 | return -EBADF; |
1327 | if (unlikely(nr_segs > UIO_MAXIOV)) | 1327 | if (unlikely(nr_segs > UIO_MAXIOV)) |
@@ -1549,8 +1549,8 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1549 | static long do_tee(struct file *in, struct file *out, size_t len, | 1549 | static long do_tee(struct file *in, struct file *out, size_t len, |
1550 | unsigned int flags) | 1550 | unsigned int flags) |
1551 | { | 1551 | { |
1552 | struct pipe_inode_info *ipipe = pipe_info(in->f_dentry->d_inode); | 1552 | struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode); |
1553 | struct pipe_inode_info *opipe = pipe_info(out->f_dentry->d_inode); | 1553 | struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode); |
1554 | int ret = -EINVAL; | 1554 | int ret = -EINVAL; |
1555 | 1555 | ||
1556 | /* | 1556 | /* |
diff --git a/fs/stack.c b/fs/stack.c new file mode 100644 index 000000000000..8ffb880d2f46 --- /dev/null +++ b/fs/stack.c | |||
@@ -0,0 +1,38 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/fs.h> | ||
3 | #include <linux/fs_stack.h> | ||
4 | |||
5 | /* does _NOT_ require i_mutex to be held. | ||
6 | * | ||
7 | * This function cannot be inlined since i_size_{read,write} is rather | ||
8 | * heavy-weight on 32-bit systems | ||
9 | */ | ||
10 | void fsstack_copy_inode_size(struct inode *dst, const struct inode *src) | ||
11 | { | ||
12 | i_size_write(dst, i_size_read((struct inode *)src)); | ||
13 | dst->i_blocks = src->i_blocks; | ||
14 | } | ||
15 | EXPORT_SYMBOL_GPL(fsstack_copy_inode_size); | ||
16 | |||
17 | /* copy all attributes; get_nlinks is optional way to override the i_nlink | ||
18 | * copying | ||
19 | */ | ||
20 | void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, | ||
21 | int (*get_nlinks)(struct inode *)) | ||
22 | { | ||
23 | if (!get_nlinks) | ||
24 | dest->i_nlink = src->i_nlink; | ||
25 | else | ||
26 | dest->i_nlink = (*get_nlinks)(dest); | ||
27 | |||
28 | dest->i_mode = src->i_mode; | ||
29 | dest->i_uid = src->i_uid; | ||
30 | dest->i_gid = src->i_gid; | ||
31 | dest->i_rdev = src->i_rdev; | ||
32 | dest->i_atime = src->i_atime; | ||
33 | dest->i_mtime = src->i_mtime; | ||
34 | dest->i_ctime = src->i_ctime; | ||
35 | dest->i_blkbits = src->i_blkbits; | ||
36 | dest->i_flags = src->i_flags; | ||
37 | } | ||
38 | EXPORT_SYMBOL_GPL(fsstack_copy_attr_all); | ||
@@ -51,13 +51,6 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
51 | return inode->i_op->getattr(mnt, dentry, stat); | 51 | return inode->i_op->getattr(mnt, dentry, stat); |
52 | 52 | ||
53 | generic_fillattr(inode, stat); | 53 | generic_fillattr(inode, stat); |
54 | if (!stat->blksize) { | ||
55 | struct super_block *s = inode->i_sb; | ||
56 | unsigned blocks; | ||
57 | blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits; | ||
58 | stat->blocks = (s->s_blocksize / 512) * blocks; | ||
59 | stat->blksize = s->s_blocksize; | ||
60 | } | ||
61 | return 0; | 54 | return 0; |
62 | } | 55 | } |
63 | 56 | ||
@@ -109,7 +102,7 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) | |||
109 | int error = -EBADF; | 102 | int error = -EBADF; |
110 | 103 | ||
111 | if (f) { | 104 | if (f) { |
112 | error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat); | 105 | error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); |
113 | fput(f); | 106 | fput(f); |
114 | } | 107 | } |
115 | return error; | 108 | return error; |
diff --git a/fs/super.c b/fs/super.c index 47e554c12e76..3e7458c2bb76 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -221,6 +221,24 @@ static int grab_super(struct super_block *s) __releases(sb_lock) | |||
221 | } | 221 | } |
222 | 222 | ||
223 | /* | 223 | /* |
224 | * Superblock locking. We really ought to get rid of these two. | ||
225 | */ | ||
226 | void lock_super(struct super_block * sb) | ||
227 | { | ||
228 | get_fs_excl(); | ||
229 | mutex_lock(&sb->s_lock); | ||
230 | } | ||
231 | |||
232 | void unlock_super(struct super_block * sb) | ||
233 | { | ||
234 | put_fs_excl(); | ||
235 | mutex_unlock(&sb->s_lock); | ||
236 | } | ||
237 | |||
238 | EXPORT_SYMBOL(lock_super); | ||
239 | EXPORT_SYMBOL(unlock_super); | ||
240 | |||
241 | /* | ||
224 | * Write out and wait upon all dirty data associated with this | 242 | * Write out and wait upon all dirty data associated with this |
225 | * superblock. Filesystem data as well as the underlying block | 243 | * superblock. Filesystem data as well as the underlying block |
226 | * device. Takes the superblock lock. Requires a second blkdev | 244 | * device. Takes the superblock lock. Requires a second blkdev |
@@ -552,7 +570,7 @@ static void mark_files_ro(struct super_block *sb) | |||
552 | 570 | ||
553 | file_list_lock(); | 571 | file_list_lock(); |
554 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | 572 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { |
555 | if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f)) | 573 | if (S_ISREG(f->f_path.dentry->d_inode->i_mode) && file_count(f)) |
556 | f->f_mode &= ~FMODE_WRITE; | 574 | f->f_mode &= ~FMODE_WRITE; |
557 | } | 575 | } |
558 | file_list_unlock(); | 576 | file_list_unlock(); |
@@ -735,9 +753,9 @@ int get_sb_bdev(struct file_system_type *fs_type, | |||
735 | * will protect the lockfs code from trying to start a snapshot | 753 | * will protect the lockfs code from trying to start a snapshot |
736 | * while we are mounting | 754 | * while we are mounting |
737 | */ | 755 | */ |
738 | mutex_lock(&bdev->bd_mount_mutex); | 756 | down(&bdev->bd_mount_sem); |
739 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); | 757 | s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); |
740 | mutex_unlock(&bdev->bd_mount_mutex); | 758 | up(&bdev->bd_mount_sem); |
741 | if (IS_ERR(s)) | 759 | if (IS_ERR(s)) |
742 | goto error_s; | 760 | goto error_s; |
743 | 761 | ||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/file.h> | 6 | #include <linux/file.h> |
7 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/sched.h> | ||
9 | #include <linux/writeback.h> | 10 | #include <linux/writeback.h> |
10 | #include <linux/syscalls.h> | 11 | #include <linux/syscalls.h> |
11 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
@@ -93,7 +94,7 @@ long do_fsync(struct file *file, int datasync) | |||
93 | * livelocks in fsync_buffers_list(). | 94 | * livelocks in fsync_buffers_list(). |
94 | */ | 95 | */ |
95 | mutex_lock(&mapping->host->i_mutex); | 96 | mutex_lock(&mapping->host->i_mutex); |
96 | err = file->f_op->fsync(file, file->f_dentry, datasync); | 97 | err = file->f_op->fsync(file, file->f_path.dentry, datasync); |
97 | if (!ret) | 98 | if (!ret) |
98 | ret = err; | 99 | ret = err; |
99 | mutex_unlock(&mapping->host->i_mutex); | 100 | mutex_unlock(&mapping->host->i_mutex); |
@@ -222,7 +223,7 @@ asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | |||
222 | if (!file) | 223 | if (!file) |
223 | goto out; | 224 | goto out; |
224 | 225 | ||
225 | i_mode = file->f_dentry->d_inode->i_mode; | 226 | i_mode = file->f_path.dentry->d_inode->i_mode; |
226 | ret = -ESPIPE; | 227 | ret = -ESPIPE; |
227 | if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) && | 228 | if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) && |
228 | !S_ISLNK(i_mode)) | 229 | !S_ISLNK(i_mode)) |
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 98022e41cda1..e8f540d38d48 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
@@ -35,7 +35,7 @@ static ssize_t | |||
35 | read(struct file * file, char __user * userbuf, size_t count, loff_t * off) | 35 | read(struct file * file, char __user * userbuf, size_t count, loff_t * off) |
36 | { | 36 | { |
37 | char *buffer = file->private_data; | 37 | char *buffer = file->private_data; |
38 | struct dentry *dentry = file->f_dentry; | 38 | struct dentry *dentry = file->f_path.dentry; |
39 | int size = dentry->d_inode->i_size; | 39 | int size = dentry->d_inode->i_size; |
40 | loff_t offs = *off; | 40 | loff_t offs = *off; |
41 | int ret; | 41 | int ret; |
@@ -81,7 +81,7 @@ static ssize_t write(struct file * file, const char __user * userbuf, | |||
81 | size_t count, loff_t * off) | 81 | size_t count, loff_t * off) |
82 | { | 82 | { |
83 | char *buffer = file->private_data; | 83 | char *buffer = file->private_data; |
84 | struct dentry *dentry = file->f_dentry; | 84 | struct dentry *dentry = file->f_path.dentry; |
85 | int size = dentry->d_inode->i_size; | 85 | int size = dentry->d_inode->i_size; |
86 | loff_t offs = *off; | 86 | loff_t offs = *off; |
87 | 87 | ||
@@ -105,7 +105,7 @@ static ssize_t write(struct file * file, const char __user * userbuf, | |||
105 | 105 | ||
106 | static int mmap(struct file *file, struct vm_area_struct *vma) | 106 | static int mmap(struct file *file, struct vm_area_struct *vma) |
107 | { | 107 | { |
108 | struct dentry *dentry = file->f_dentry; | 108 | struct dentry *dentry = file->f_path.dentry; |
109 | struct bin_attribute *attr = to_bin_attr(dentry); | 109 | struct bin_attribute *attr = to_bin_attr(dentry); |
110 | struct kobject *kobj = to_kobj(dentry->d_parent); | 110 | struct kobject *kobj = to_kobj(dentry->d_parent); |
111 | 111 | ||
@@ -117,8 +117,8 @@ static int mmap(struct file *file, struct vm_area_struct *vma) | |||
117 | 117 | ||
118 | static int open(struct inode * inode, struct file * file) | 118 | static int open(struct inode * inode, struct file * file) |
119 | { | 119 | { |
120 | struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent); | 120 | struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent); |
121 | struct bin_attribute * attr = to_bin_attr(file->f_dentry); | 121 | struct bin_attribute * attr = to_bin_attr(file->f_path.dentry); |
122 | int error = -EINVAL; | 122 | int error = -EINVAL; |
123 | 123 | ||
124 | if (!kobj || !attr) | 124 | if (!kobj || !attr) |
@@ -153,8 +153,8 @@ static int open(struct inode * inode, struct file * file) | |||
153 | 153 | ||
154 | static int release(struct inode * inode, struct file * file) | 154 | static int release(struct inode * inode, struct file * file) |
155 | { | 155 | { |
156 | struct kobject * kobj = to_kobj(file->f_dentry->d_parent); | 156 | struct kobject * kobj = to_kobj(file->f_path.dentry->d_parent); |
157 | struct bin_attribute * attr = to_bin_attr(file->f_dentry); | 157 | struct bin_attribute * attr = to_bin_attr(file->f_path.dentry); |
158 | u8 * buffer = file->private_data; | 158 | u8 * buffer = file->private_data; |
159 | 159 | ||
160 | if (kobj) | 160 | if (kobj) |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 3aa3434621ca..511edef8b321 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -372,9 +372,54 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
372 | return error; | 372 | return error; |
373 | } | 373 | } |
374 | 374 | ||
375 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) | ||
376 | { | ||
377 | struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; | ||
378 | struct sysfs_dirent *new_parent_sd, *sd; | ||
379 | int error; | ||
380 | |||
381 | if (!new_parent) | ||
382 | return -EINVAL; | ||
383 | |||
384 | old_parent_dentry = kobj->parent ? | ||
385 | kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; | ||
386 | new_parent_dentry = new_parent->dentry; | ||
387 | |||
388 | again: | ||
389 | mutex_lock(&old_parent_dentry->d_inode->i_mutex); | ||
390 | if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { | ||
391 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
392 | goto again; | ||
393 | } | ||
394 | |||
395 | new_parent_sd = new_parent_dentry->d_fsdata; | ||
396 | sd = kobj->dentry->d_fsdata; | ||
397 | |||
398 | new_dentry = lookup_one_len(kobj->name, new_parent_dentry, | ||
399 | strlen(kobj->name)); | ||
400 | if (IS_ERR(new_dentry)) { | ||
401 | error = PTR_ERR(new_dentry); | ||
402 | goto out; | ||
403 | } else | ||
404 | error = 0; | ||
405 | d_add(new_dentry, NULL); | ||
406 | d_move(kobj->dentry, new_dentry); | ||
407 | dput(new_dentry); | ||
408 | |||
409 | /* Remove from old parent's list and insert into new parent's list. */ | ||
410 | list_del_init(&sd->s_sibling); | ||
411 | list_add(&sd->s_sibling, &new_parent_sd->s_children); | ||
412 | |||
413 | out: | ||
414 | mutex_unlock(&new_parent_dentry->d_inode->i_mutex); | ||
415 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
416 | |||
417 | return error; | ||
418 | } | ||
419 | |||
375 | static int sysfs_dir_open(struct inode *inode, struct file *file) | 420 | static int sysfs_dir_open(struct inode *inode, struct file *file) |
376 | { | 421 | { |
377 | struct dentry * dentry = file->f_dentry; | 422 | struct dentry * dentry = file->f_path.dentry; |
378 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 423 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; |
379 | 424 | ||
380 | mutex_lock(&dentry->d_inode->i_mutex); | 425 | mutex_lock(&dentry->d_inode->i_mutex); |
@@ -387,7 +432,7 @@ static int sysfs_dir_open(struct inode *inode, struct file *file) | |||
387 | 432 | ||
388 | static int sysfs_dir_close(struct inode *inode, struct file *file) | 433 | static int sysfs_dir_close(struct inode *inode, struct file *file) |
389 | { | 434 | { |
390 | struct dentry * dentry = file->f_dentry; | 435 | struct dentry * dentry = file->f_path.dentry; |
391 | struct sysfs_dirent * cursor = file->private_data; | 436 | struct sysfs_dirent * cursor = file->private_data; |
392 | 437 | ||
393 | mutex_lock(&dentry->d_inode->i_mutex); | 438 | mutex_lock(&dentry->d_inode->i_mutex); |
@@ -407,7 +452,7 @@ static inline unsigned char dt_type(struct sysfs_dirent *sd) | |||
407 | 452 | ||
408 | static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | 453 | static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) |
409 | { | 454 | { |
410 | struct dentry *dentry = filp->f_dentry; | 455 | struct dentry *dentry = filp->f_path.dentry; |
411 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 456 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; |
412 | struct sysfs_dirent *cursor = filp->private_data; | 457 | struct sysfs_dirent *cursor = filp->private_data; |
413 | struct list_head *p, *q = &cursor->s_sibling; | 458 | struct list_head *p, *q = &cursor->s_sibling; |
@@ -464,7 +509,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
464 | 509 | ||
465 | static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | 510 | static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) |
466 | { | 511 | { |
467 | struct dentry * dentry = file->f_dentry; | 512 | struct dentry * dentry = file->f_path.dentry; |
468 | 513 | ||
469 | mutex_lock(&dentry->d_inode->i_mutex); | 514 | mutex_lock(&dentry->d_inode->i_mutex); |
470 | switch (origin) { | 515 | switch (origin) { |
@@ -474,7 +519,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin) | |||
474 | if (offset >= 0) | 519 | if (offset >= 0) |
475 | break; | 520 | break; |
476 | default: | 521 | default: |
477 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 522 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
478 | return -EINVAL; | 523 | return -EINVAL; |
479 | } | 524 | } |
480 | if (offset != file->f_pos) { | 525 | if (offset != file->f_pos) { |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 298303b5a716..9cfe53e1e00d 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -154,7 +154,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
154 | 154 | ||
155 | down(&buffer->sem); | 155 | down(&buffer->sem); |
156 | if (buffer->needs_read_fill) { | 156 | if (buffer->needs_read_fill) { |
157 | if ((retval = fill_read_buffer(file->f_dentry,buffer))) | 157 | if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) |
158 | goto out; | 158 | goto out; |
159 | } | 159 | } |
160 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", | 160 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
@@ -190,6 +190,9 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t | |||
190 | count = PAGE_SIZE - 1; | 190 | count = PAGE_SIZE - 1; |
191 | error = copy_from_user(buffer->page,buf,count); | 191 | error = copy_from_user(buffer->page,buf,count); |
192 | buffer->needs_read_fill = 1; | 192 | buffer->needs_read_fill = 1; |
193 | /* if buf is assumed to contain a string, terminate it by \0, | ||
194 | so e.g. sscanf() can scan the string easily */ | ||
195 | buffer->page[count] = 0; | ||
193 | return error ? -EFAULT : count; | 196 | return error ? -EFAULT : count; |
194 | } | 197 | } |
195 | 198 | ||
@@ -242,7 +245,7 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t | |||
242 | down(&buffer->sem); | 245 | down(&buffer->sem); |
243 | len = fill_write_buffer(buffer, buf, count); | 246 | len = fill_write_buffer(buffer, buf, count); |
244 | if (len > 0) | 247 | if (len > 0) |
245 | len = flush_write_buffer(file->f_dentry, buffer, len); | 248 | len = flush_write_buffer(file->f_path.dentry, buffer, len); |
246 | if (len > 0) | 249 | if (len > 0) |
247 | *ppos += len; | 250 | *ppos += len; |
248 | up(&buffer->sem); | 251 | up(&buffer->sem); |
@@ -251,8 +254,8 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t | |||
251 | 254 | ||
252 | static int check_perm(struct inode * inode, struct file * file) | 255 | static int check_perm(struct inode * inode, struct file * file) |
253 | { | 256 | { |
254 | struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent); | 257 | struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent); |
255 | struct attribute * attr = to_attr(file->f_dentry); | 258 | struct attribute * attr = to_attr(file->f_path.dentry); |
256 | struct sysfs_buffer * buffer; | 259 | struct sysfs_buffer * buffer; |
257 | struct sysfs_ops * ops = NULL; | 260 | struct sysfs_ops * ops = NULL; |
258 | int error = 0; | 261 | int error = 0; |
@@ -334,8 +337,8 @@ static int sysfs_open_file(struct inode * inode, struct file * filp) | |||
334 | 337 | ||
335 | static int sysfs_release(struct inode * inode, struct file * filp) | 338 | static int sysfs_release(struct inode * inode, struct file * filp) |
336 | { | 339 | { |
337 | struct kobject * kobj = to_kobj(filp->f_dentry->d_parent); | 340 | struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent); |
338 | struct attribute * attr = to_attr(filp->f_dentry); | 341 | struct attribute * attr = to_attr(filp->f_path.dentry); |
339 | struct module * owner = attr->owner; | 342 | struct module * owner = attr->owner; |
340 | struct sysfs_buffer * buffer = filp->private_data; | 343 | struct sysfs_buffer * buffer = filp->private_data; |
341 | 344 | ||
@@ -369,8 +372,8 @@ static int sysfs_release(struct inode * inode, struct file * filp) | |||
369 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | 372 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) |
370 | { | 373 | { |
371 | struct sysfs_buffer * buffer = filp->private_data; | 374 | struct sysfs_buffer * buffer = filp->private_data; |
372 | struct kobject * kobj = to_kobj(filp->f_dentry->d_parent); | 375 | struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent); |
373 | struct sysfs_dirent * sd = filp->f_dentry->d_fsdata; | 376 | struct sysfs_dirent * sd = filp->f_path.dentry->d_fsdata; |
374 | int res = 0; | 377 | int res = 0; |
375 | 378 | ||
376 | poll_wait(filp, &kobj->poll, wait); | 379 | poll_wait(filp, &kobj->poll, wait); |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 20551a1b8a56..e503f858fba8 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | struct vfsmount *sysfs_mount; | 17 | struct vfsmount *sysfs_mount; |
18 | struct super_block * sysfs_sb = NULL; | 18 | struct super_block * sysfs_sb = NULL; |
19 | kmem_cache_t *sysfs_dir_cachep; | 19 | struct kmem_cache *sysfs_dir_cachep; |
20 | 20 | ||
21 | static struct super_operations sysfs_ops = { | 21 | static struct super_operations sysfs_ops = { |
22 | .statfs = simple_statfs, | 22 | .statfs = simple_statfs, |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 6f3d6bd52887..bd7cec295dab 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | extern struct vfsmount * sysfs_mount; | 2 | extern struct vfsmount * sysfs_mount; |
3 | extern kmem_cache_t *sysfs_dir_cachep; | 3 | extern struct kmem_cache *sysfs_dir_cachep; |
4 | 4 | ||
5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); | 5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); |
6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); | 6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); |
diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES deleted file mode 100644 index 66ea6e92be66..000000000000 --- a/fs/sysv/CHANGES +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | Mon, 15 Dec 1997 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
2 | * namei.c: struct sysv_dir_inode_operations updated to use dentries. | ||
3 | |||
4 | Fri, 23 Jan 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
5 | * inode.c: corrected 1 track offset setting (in sb->sv_block_base). | ||
6 | Originally it was overridden (by setting to zero) | ||
7 | in detected_[xenix,sysv4,sysv2,coherent]. Thanks | ||
8 | to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> | ||
9 | for identifying the problem. | ||
10 | |||
11 | Tue, 27 Jan 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
12 | * inode.c: added 2048-byte block support to SystemV FS. | ||
13 | Merged detected_bs[512,1024,2048]() into one function: | ||
14 | void detected_bs (u_char type, struct super_block *sb). | ||
15 | Thanks to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> | ||
16 | for the patch. | ||
17 | |||
18 | Wed, 4 Feb 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
19 | * namei.c: removed static subdir(); is_subdir() from dcache.c | ||
20 | is used instead. Cosmetic changes. | ||
21 | |||
22 | Thu, 3 Dec 1998 Al Viro (viro@parcelfarce.linux.theplanet.co.uk) | ||
23 | * namei.c (sysv_rmdir): | ||
24 | Bugectomy: old check for victim being busy | ||
25 | (inode->i_count) wasn't replaced (with checking | ||
26 | dentry->d_count) and escaped Linus in the last round | ||
27 | of changes. Shot and buried. | ||
28 | |||
29 | Wed, 9 Dec 1998 AV | ||
30 | * namei.c (do_sysv_rename): | ||
31 | Fixed incorrect check for other owners + race. | ||
32 | Removed checks that went to VFS. | ||
33 | * namei.c (sysv_unlink): | ||
34 | Removed checks that went to VFS. | ||
35 | |||
36 | Thu, 10 Dec 1998 AV | ||
37 | * namei.c (do_mknod): | ||
38 | Removed dead code - mknod is never asked to | ||
39 | create a symlink or directory. Incidentially, | ||
40 | it wouldn't do it right if it would be called. | ||
41 | |||
42 | Sat, 26 Dec 1998 KGB | ||
43 | * inode.c (detect_sysv4): | ||
44 | Added detection of expanded s_type field (0x10, | ||
45 | 0x20 and 0x30). Forced read-only access in this case. | ||
46 | |||
47 | Sun, 21 Mar 1999 AV | ||
48 | * namei.c (sysv_link): | ||
49 | Fixed i_count usage that resulted in dcache corruption. | ||
50 | * inode.c: | ||
51 | Filled ->delete_inode() method with sysv_delete_inode(). | ||
52 | sysv_put_inode() is gone, as it tried to do ->delete_ | ||
53 | _inode()'s job. | ||
54 | * ialloc.c: (sysv_free_inode): | ||
55 | Fixed race. | ||
56 | |||
57 | Sun, 30 Apr 1999 AV | ||
58 | * namei.c (sysv_mknod): | ||
59 | Removed dead code (S_IFREG case is now passed to | ||
60 | ->create() by VFS). | ||
diff --git a/fs/sysv/ChangeLog b/fs/sysv/ChangeLog deleted file mode 100644 index f403f8b91b80..000000000000 --- a/fs/sysv/ChangeLog +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | Thu Feb 14 2002 Andrew Morton <akpm@zip.com.au> | ||
2 | |||
3 | * dir_commit_chunk(): call writeout_one_page() as well as | ||
4 | waitfor_one_page() for IS_SYNC directories, so that we | ||
5 | actually do sync the directory. (forward-port from 2.4). | ||
6 | |||
7 | Thu Feb 7 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
8 | |||
9 | * super.c: switched to ->get_sb() | ||
10 | * ChangeLog: fixed dates ;-) | ||
11 | |||
12 | 2002-01-24 David S. Miller <davem@redhat.com> | ||
13 | |||
14 | * inode.c: Include linux/init.h | ||
15 | |||
16 | Mon Jan 21 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
17 | * ialloc.c (sysv_new_inode): zero SYSV_I(inode)->i_data out. | ||
18 | * i_vnode renamed to vfs_inode. Sorry, but let's keep that | ||
19 | consistent. | ||
20 | |||
21 | Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> | ||
22 | |||
23 | * include/linux/sysv_fs.h (SYSV_I): Get fs-private inode data using | ||
24 | list_entry() instead of inode->u. | ||
25 | * include/linux/sysv_fs_i.h: Add 'struct inode i_vnode' field to | ||
26 | sysv_inode_info structure. | ||
27 | * inode.c: Include <linux/slab.h>, implement alloc_inode/destroy_inode | ||
28 | sop methods, add infrastructure for per-fs inode slab cache. | ||
29 | * super.c (init_sysv_fs): Initialize inode cache, recover properly | ||
30 | in the case of failed register_filesystem for V7. | ||
31 | (exit_sysv_fs): Destroy inode cache. | ||
32 | |||
33 | Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> | ||
34 | |||
35 | * include/linux/sysv_fs.h: Include <linux/sysv_fs_i.h>, declare SYSV_I(). | ||
36 | * dir.c (sysv_find_entry): Use SYSV_I() instead of ->u.sysv_i to | ||
37 | access fs-private inode data. | ||
38 | * ialloc.c (sysv_new_inode): Likewise. | ||
39 | * inode.c (sysv_read_inode): Likewise. | ||
40 | (sysv_update_inode): Likewise. | ||
41 | * itree.c (get_branch): Likewise. | ||
42 | (sysv_truncate): Likewise. | ||
43 | * symlink.c (sysv_readlink): Likewise. | ||
44 | (sysv_follow_link): Likewise. | ||
45 | |||
46 | Fri Jan 4 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
47 | |||
48 | * ialloc.c (sysv_free_inode): Use sb->s_id instead of bdevname(). | ||
49 | * inode.c (sysv_read_inode): Likewise. | ||
50 | (sysv_update_inode): Likewise. | ||
51 | (sysv_sync_inode): Likewise. | ||
52 | * super.c (detect_sysv): Likewise. | ||
53 | (complete_read_super): Likewise. | ||
54 | (sysv_read_super): Likewise. | ||
55 | (v7_read_super): Likewise. | ||
56 | |||
57 | Sun Dec 30 2001 Manfred Spraul <manfred@colorfullife.com> | ||
58 | |||
59 | * dir.c (dir_commit_chunk): Do not set dir->i_version. | ||
60 | (sysv_readdir): Likewise. | ||
61 | |||
62 | Thu Dec 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
63 | |||
64 | * itree.c (get_block): Use map_bh() to fill out bh_result. | ||
65 | |||
66 | Tue Dec 25 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
67 | |||
68 | * super.c (sysv_read_super): Use sb_set_blocksize() to set blocksize. | ||
69 | (v7_read_super): Likewise. | ||
70 | |||
71 | Tue Nov 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
72 | |||
73 | * itree.c (get_block): Change type for iblock argument to sector_t. | ||
74 | * super.c (sysv_read_super): Set s_blocksize early. | ||
75 | (v7_read_super): Likewise. | ||
76 | * balloc.c (sysv_new_block): Use sb_bread(). instead of bread(). | ||
77 | (sysv_count_free_blocks): Likewise. | ||
78 | * ialloc.c (sysv_raw_inode): Likewise. | ||
79 | * itree.c (get_branch): Likewise. | ||
80 | (free_branches): Likewise. | ||
81 | * super.c (sysv_read_super): Likewise. | ||
82 | (v7_read_super): Likewise. | ||
83 | |||
84 | Sat Dec 15 2001 Christoph Hellwig <hch@infradead.org> | ||
85 | |||
86 | * inode.c (sysv_read_inode): Mark inode as bad in case of failure. | ||
87 | * super.c (complete_read_super): Check for bad root inode. | ||
88 | |||
89 | Wed Nov 21 2001 Andrew Morton <andrewm@uow.edu.au> | ||
90 | |||
91 | * file.c (sysv_sync_file): Call fsync_inode_data_buffers. | ||
92 | |||
93 | Fri Oct 26 2001 Christoph Hellwig <hch@infradead.org> | ||
94 | |||
95 | * dir.c, ialloc.c, namei.c, include/linux/sysv_fs_i.h: | ||
96 | Implement per-Inode lookup offset cache. | ||
97 | Modelled after Ted's ext2 patch. | ||
98 | |||
99 | Fri Oct 26 2001 Christoph Hellwig <hch@infradead.org> | ||
100 | |||
101 | * inode.c, super.c, include/linux/sysv_fs.h, | ||
102 | include/linux/sysv_fs_sb.h: | ||
103 | Remove symlink faking. Noone really wants to use these as | ||
104 | linux filesystems and native OSes don't support it anyway. | ||
105 | |||
106 | |||
diff --git a/fs/sysv/INTRO b/fs/sysv/INTRO deleted file mode 100644 index de4e4d17cac6..000000000000 --- a/fs/sysv/INTRO +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | This is the implementation of the SystemV/Coherent filesystem for Linux. | ||
2 | It grew out of separate filesystem implementations | ||
3 | |||
4 | Xenix FS Doug Evans <dje@cygnus.com> June 1992 | ||
5 | SystemV FS Paul B. Monday <pmonday@eecs.wsu.edu> March-June 1993 | ||
6 | Coherent FS B. Haible <haible@ma2s2.mathematik.uni-karlsruhe.de> June 1993 | ||
7 | |||
8 | and was merged together in July 1993. | ||
9 | |||
10 | These filesystems are rather similar. Here is a comparison with Minix FS: | ||
11 | |||
12 | * Linux fdisk reports on partitions | ||
13 | - Minix FS 0x81 Linux/Minix | ||
14 | - Xenix FS ?? | ||
15 | - SystemV FS ?? | ||
16 | - Coherent FS 0x08 AIX bootable | ||
17 | |||
18 | * Size of a block or zone (data allocation unit on disk) | ||
19 | - Minix FS 1024 | ||
20 | - Xenix FS 1024 (also 512 ??) | ||
21 | - SystemV FS 1024 (also 512 and 2048) | ||
22 | - Coherent FS 512 | ||
23 | |||
24 | * General layout: all have one boot block, one super block and | ||
25 | separate areas for inodes and for directories/data. | ||
26 | On SystemV Release 2 FS (e.g. Microport) the first track is reserved and | ||
27 | all the block numbers (including the super block) are offset by one track. | ||
28 | |||
29 | * Byte ordering of "short" (16 bit entities) on disk: | ||
30 | - Minix FS little endian 0 1 | ||
31 | - Xenix FS little endian 0 1 | ||
32 | - SystemV FS little endian 0 1 | ||
33 | - Coherent FS little endian 0 1 | ||
34 | Of course, this affects only the file system, not the data of files on it! | ||
35 | |||
36 | * Byte ordering of "long" (32 bit entities) on disk: | ||
37 | - Minix FS little endian 0 1 2 3 | ||
38 | - Xenix FS little endian 0 1 2 3 | ||
39 | - SystemV FS little endian 0 1 2 3 | ||
40 | - Coherent FS PDP-11 2 3 0 1 | ||
41 | Of course, this affects only the file system, not the data of files on it! | ||
42 | |||
43 | * Inode on disk: "short", 0 means non-existent, the root dir ino is: | ||
44 | - Minix FS 1 | ||
45 | - Xenix FS, SystemV FS, Coherent FS 2 | ||
46 | |||
47 | * Maximum number of hard links to a file: | ||
48 | - Minix FS 250 | ||
49 | - Xenix FS ?? | ||
50 | - SystemV FS ?? | ||
51 | - Coherent FS >=10000 | ||
52 | |||
53 | * Free inode management: | ||
54 | - Minix FS a bitmap | ||
55 | - Xenix FS, SystemV FS, Coherent FS | ||
56 | There is a cache of a certain number of free inodes in the super-block. | ||
57 | When it is exhausted, new free inodes are found using a linear search. | ||
58 | |||
59 | * Free block management: | ||
60 | - Minix FS a bitmap | ||
61 | - Xenix FS, SystemV FS, Coherent FS | ||
62 | Free blocks are organized in a "free list". Maybe a misleading term, | ||
63 | since it is not true that every free block contains a pointer to | ||
64 | the next free block. Rather, the free blocks are organized in chunks | ||
65 | of limited size, and every now and then a free block contains pointers | ||
66 | to the free blocks pertaining to the next chunk; the first of these | ||
67 | contains pointers and so on. The list terminates with a "block number" | ||
68 | 0 on Xenix FS and SystemV FS, with a block zeroed out on Coherent FS. | ||
69 | |||
70 | * Super-block location: | ||
71 | - Minix FS block 1 = bytes 1024..2047 | ||
72 | - Xenix FS block 1 = bytes 1024..2047 | ||
73 | - SystemV FS bytes 512..1023 | ||
74 | - Coherent FS block 1 = bytes 512..1023 | ||
75 | |||
76 | * Super-block layout: | ||
77 | - Minix FS | ||
78 | unsigned short s_ninodes; | ||
79 | unsigned short s_nzones; | ||
80 | unsigned short s_imap_blocks; | ||
81 | unsigned short s_zmap_blocks; | ||
82 | unsigned short s_firstdatazone; | ||
83 | unsigned short s_log_zone_size; | ||
84 | unsigned long s_max_size; | ||
85 | unsigned short s_magic; | ||
86 | - Xenix FS, SystemV FS, Coherent FS | ||
87 | unsigned short s_firstdatazone; | ||
88 | unsigned long s_nzones; | ||
89 | unsigned short s_fzone_count; | ||
90 | unsigned long s_fzones[NICFREE]; | ||
91 | unsigned short s_finode_count; | ||
92 | unsigned short s_finodes[NICINOD]; | ||
93 | char s_flock; | ||
94 | char s_ilock; | ||
95 | char s_modified; | ||
96 | char s_rdonly; | ||
97 | unsigned long s_time; | ||
98 | short s_dinfo[4]; -- SystemV FS only | ||
99 | unsigned long s_free_zones; | ||
100 | unsigned short s_free_inodes; | ||
101 | short s_dinfo[4]; -- Xenix FS only | ||
102 | unsigned short s_interleave_m,s_interleave_n; -- Coherent FS only | ||
103 | char s_fname[6]; | ||
104 | char s_fpack[6]; | ||
105 | then they differ considerably: | ||
106 | Xenix FS | ||
107 | char s_clean; | ||
108 | char s_fill[371]; | ||
109 | long s_magic; | ||
110 | long s_type; | ||
111 | SystemV FS | ||
112 | long s_fill[12 or 14]; | ||
113 | long s_state; | ||
114 | long s_magic; | ||
115 | long s_type; | ||
116 | Coherent FS | ||
117 | unsigned long s_unique; | ||
118 | Note that Coherent FS has no magic. | ||
119 | |||
120 | * Inode layout: | ||
121 | - Minix FS | ||
122 | unsigned short i_mode; | ||
123 | unsigned short i_uid; | ||
124 | unsigned long i_size; | ||
125 | unsigned long i_time; | ||
126 | unsigned char i_gid; | ||
127 | unsigned char i_nlinks; | ||
128 | unsigned short i_zone[7+1+1]; | ||
129 | - Xenix FS, SystemV FS, Coherent FS | ||
130 | unsigned short i_mode; | ||
131 | unsigned short i_nlink; | ||
132 | unsigned short i_uid; | ||
133 | unsigned short i_gid; | ||
134 | unsigned long i_size; | ||
135 | unsigned char i_zone[3*(10+1+1+1)]; | ||
136 | unsigned long i_atime; | ||
137 | unsigned long i_mtime; | ||
138 | unsigned long i_ctime; | ||
139 | |||
140 | * Regular file data blocks are organized as | ||
141 | - Minix FS | ||
142 | 7 direct blocks | ||
143 | 1 indirect block (pointers to blocks) | ||
144 | 1 double-indirect block (pointer to pointers to blocks) | ||
145 | - Xenix FS, SystemV FS, Coherent FS | ||
146 | 10 direct blocks | ||
147 | 1 indirect block (pointers to blocks) | ||
148 | 1 double-indirect block (pointer to pointers to blocks) | ||
149 | 1 triple-indirect block (pointer to pointers to pointers to blocks) | ||
150 | |||
151 | * Inode size, inodes per block | ||
152 | - Minix FS 32 32 | ||
153 | - Xenix FS 64 16 | ||
154 | - SystemV FS 64 16 | ||
155 | - Coherent FS 64 8 | ||
156 | |||
157 | * Directory entry on disk | ||
158 | - Minix FS | ||
159 | unsigned short inode; | ||
160 | char name[14/30]; | ||
161 | - Xenix FS, SystemV FS, Coherent FS | ||
162 | unsigned short inode; | ||
163 | char name[14]; | ||
164 | |||
165 | * Dir entry size, dir entries per block | ||
166 | - Minix FS 16/32 64/32 | ||
167 | - Xenix FS 16 64 | ||
168 | - SystemV FS 16 64 | ||
169 | - Coherent FS 16 32 | ||
170 | |||
171 | * How to implement symbolic links such that the host fsck doesn't scream: | ||
172 | - Minix FS normal | ||
173 | - Xenix FS kludge: as regular files with chmod 1000 | ||
174 | - SystemV FS ?? | ||
175 | - Coherent FS kludge: as regular files with chmod 1000 | ||
176 | |||
177 | |||
178 | Notation: We often speak of a "block" but mean a zone (the allocation unit) | ||
179 | and not the disk driver's notion of "block". | ||
180 | |||
181 | |||
182 | Bruno Haible <haible@ma2s2.mathematik.uni-karlsruhe.de> | ||
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index f2bef962d309..ebf7007fa161 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -70,7 +70,7 @@ fail: | |||
70 | static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | 70 | static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) |
71 | { | 71 | { |
72 | unsigned long pos = filp->f_pos; | 72 | unsigned long pos = filp->f_pos; |
73 | struct inode *inode = filp->f_dentry->d_inode; | 73 | struct inode *inode = filp->f_path.dentry->d_inode; |
74 | struct super_block *sb = inode->i_sb; | 74 | struct super_block *sb = inode->i_sb; |
75 | unsigned offset = pos & ~PAGE_CACHE_MASK; | 75 | unsigned offset = pos & ~PAGE_CACHE_MASK; |
76 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 76 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index d63c5e48b050..ead9864567e3 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -301,13 +301,13 @@ static void sysv_delete_inode(struct inode *inode) | |||
301 | unlock_kernel(); | 301 | unlock_kernel(); |
302 | } | 302 | } |
303 | 303 | ||
304 | static kmem_cache_t *sysv_inode_cachep; | 304 | static struct kmem_cache *sysv_inode_cachep; |
305 | 305 | ||
306 | static struct inode *sysv_alloc_inode(struct super_block *sb) | 306 | static struct inode *sysv_alloc_inode(struct super_block *sb) |
307 | { | 307 | { |
308 | struct sysv_inode_info *si; | 308 | struct sysv_inode_info *si; |
309 | 309 | ||
310 | si = kmem_cache_alloc(sysv_inode_cachep, SLAB_KERNEL); | 310 | si = kmem_cache_alloc(sysv_inode_cachep, GFP_KERNEL); |
311 | if (!si) | 311 | if (!si) |
312 | return NULL; | 312 | return NULL; |
313 | return &si->vfs_inode; | 313 | return &si->vfs_inode; |
@@ -318,7 +318,7 @@ static void sysv_destroy_inode(struct inode *inode) | |||
318 | kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); | 318 | kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 321 | static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
322 | { | 322 | { |
323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; | 323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; |
324 | 324 | ||
diff --git a/fs/sysv/super.c b/fs/sysv/super.c index dc9e7dc07fb7..6f9707a1b954 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c | |||
@@ -528,9 +528,6 @@ static struct file_system_type v7_fs_type = { | |||
528 | .fs_flags = FS_REQUIRES_DEV, | 528 | .fs_flags = FS_REQUIRES_DEV, |
529 | }; | 529 | }; |
530 | 530 | ||
531 | extern int sysv_init_icache(void) __init; | ||
532 | extern void sysv_destroy_icache(void); | ||
533 | |||
534 | static int __init init_sysv_fs(void) | 531 | static int __init init_sysv_fs(void) |
535 | { | 532 | { |
536 | int error; | 533 | int error; |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 9dcc82120935..dcb18b2171fe 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h | |||
@@ -143,6 +143,9 @@ extern int sysv_sync_inode(struct inode *); | |||
143 | extern int sysv_sync_file(struct file *, struct dentry *, int); | 143 | extern int sysv_sync_file(struct file *, struct dentry *, int); |
144 | extern void sysv_set_inode(struct inode *, dev_t); | 144 | extern void sysv_set_inode(struct inode *, dev_t); |
145 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 145 | extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
146 | extern int sysv_init_icache(void); | ||
147 | extern void sysv_destroy_icache(void); | ||
148 | |||
146 | 149 | ||
147 | /* dir.c */ | 150 | /* dir.c */ |
148 | extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **); | 151 | extern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **); |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 8c28efa3b8ff..2391c9150c49 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -77,7 +77,7 @@ const struct file_operations udf_dir_operations = { | |||
77 | 77 | ||
78 | int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) | 78 | int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) |
79 | { | 79 | { |
80 | struct inode *dir = filp->f_dentry->d_inode; | 80 | struct inode *dir = filp->f_path.dentry->d_inode; |
81 | int result; | 81 | int result; |
82 | 82 | ||
83 | lock_kernel(); | 83 | lock_kernel(); |
@@ -225,7 +225,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d | |||
225 | 225 | ||
226 | if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT ) | 226 | if ( cfi.fileCharacteristics & FID_FILE_CHAR_PARENT ) |
227 | { | 227 | { |
228 | iblock = parent_ino(filp->f_dentry); | 228 | iblock = parent_ino(filp->f_path.dentry); |
229 | flen = 2; | 229 | flen = 2; |
230 | memcpy(fname, "..", flen); | 230 | memcpy(fname, "..", flen); |
231 | dt_type = DT_DIR; | 231 | dt_type = DT_DIR; |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 7aedd552cba1..d81f2db7b0e3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -108,7 +108,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
108 | { | 108 | { |
109 | ssize_t retval; | 109 | ssize_t retval; |
110 | struct file *file = iocb->ki_filp; | 110 | struct file *file = iocb->ki_filp; |
111 | struct inode *inode = file->f_dentry->d_inode; | 111 | struct inode *inode = file->f_path.dentry->d_inode; |
112 | int err, pos; | 112 | int err, pos; |
113 | size_t count = iocb->ki_left; | 113 | size_t count = iocb->ki_left; |
114 | 114 | ||
diff --git a/fs/udf/super.c b/fs/udf/super.c index 1aea6a4f9a4a..1dbc2955f02e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -107,12 +107,12 @@ static struct file_system_type udf_fstype = { | |||
107 | .fs_flags = FS_REQUIRES_DEV, | 107 | .fs_flags = FS_REQUIRES_DEV, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static kmem_cache_t * udf_inode_cachep; | 110 | static struct kmem_cache * udf_inode_cachep; |
111 | 111 | ||
112 | static struct inode *udf_alloc_inode(struct super_block *sb) | 112 | static struct inode *udf_alloc_inode(struct super_block *sb) |
113 | { | 113 | { |
114 | struct udf_inode_info *ei; | 114 | struct udf_inode_info *ei; |
115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); | 115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL); |
116 | if (!ei) | 116 | if (!ei) |
117 | return NULL; | 117 | return NULL; |
118 | 118 | ||
@@ -130,7 +130,7 @@ static void udf_destroy_inode(struct inode *inode) | |||
130 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); | 130 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 133 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
134 | { | 134 | { |
135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; | 135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; |
136 | 136 | ||
@@ -1709,7 +1709,7 @@ void udf_error(struct super_block *sb, const char *function, | |||
1709 | sb->s_dirt = 1; | 1709 | sb->s_dirt = 1; |
1710 | } | 1710 | } |
1711 | va_start(args, fmt); | 1711 | va_start(args, fmt); |
1712 | vsprintf(error_buf, fmt, args); | 1712 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1713 | va_end(args); | 1713 | va_end(args); |
1714 | printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", | 1714 | printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", |
1715 | sb->s_id, function, error_buf); | 1715 | sb->s_id, function, error_buf); |
@@ -1721,7 +1721,7 @@ void udf_warning(struct super_block *sb, const char *function, | |||
1721 | va_list args; | 1721 | va_list args; |
1722 | 1722 | ||
1723 | va_start (args, fmt); | 1723 | va_start (args, fmt); |
1724 | vsprintf(error_buf, fmt, args); | 1724 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1725 | va_end(args); | 1725 | va_end(args); |
1726 | printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", | 1726 | printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", |
1727 | sb->s_id, function, error_buf); | 1727 | sb->s_id, function, error_buf); |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index b82381475779..2e0021e8f366 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -275,6 +275,25 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, | |||
275 | UFSD("EXIT\n"); | 275 | UFSD("EXIT\n"); |
276 | } | 276 | } |
277 | 277 | ||
278 | static void ufs_clear_frags(struct inode *inode, sector_t beg, unsigned int n, | ||
279 | int sync) | ||
280 | { | ||
281 | struct buffer_head *bh; | ||
282 | sector_t end = beg + n; | ||
283 | |||
284 | for (; beg < end; ++beg) { | ||
285 | bh = sb_getblk(inode->i_sb, beg); | ||
286 | lock_buffer(bh); | ||
287 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | ||
288 | set_buffer_uptodate(bh); | ||
289 | mark_buffer_dirty(bh); | ||
290 | unlock_buffer(bh); | ||
291 | if (IS_SYNC(inode) || sync) | ||
292 | sync_dirty_buffer(bh); | ||
293 | brelse(bh); | ||
294 | } | ||
295 | } | ||
296 | |||
278 | unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | 297 | unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, |
279 | unsigned goal, unsigned count, int * err, struct page *locked_page) | 298 | unsigned goal, unsigned count, int * err, struct page *locked_page) |
280 | { | 299 | { |
@@ -350,6 +369,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
350 | *p = cpu_to_fs32(sb, result); | 369 | *p = cpu_to_fs32(sb, result); |
351 | *err = 0; | 370 | *err = 0; |
352 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 371 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
372 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | ||
373 | locked_page != NULL); | ||
353 | } | 374 | } |
354 | unlock_super(sb); | 375 | unlock_super(sb); |
355 | UFSD("EXIT, result %u\n", result); | 376 | UFSD("EXIT, result %u\n", result); |
@@ -363,6 +384,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
363 | if (result) { | 384 | if (result) { |
364 | *err = 0; | 385 | *err = 0; |
365 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 386 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
387 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | ||
388 | locked_page != NULL); | ||
366 | unlock_super(sb); | 389 | unlock_super(sb); |
367 | UFSD("EXIT, result %u\n", result); | 390 | UFSD("EXIT, result %u\n", result); |
368 | return result; | 391 | return result; |
@@ -398,6 +421,8 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment, | |||
398 | *p = cpu_to_fs32(sb, result); | 421 | *p = cpu_to_fs32(sb, result); |
399 | *err = 0; | 422 | *err = 0; |
400 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 423 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
424 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | ||
425 | locked_page != NULL); | ||
401 | unlock_super(sb); | 426 | unlock_super(sb); |
402 | if (newcount < request) | 427 | if (newcount < request) |
403 | ufs_free_fragments (inode, result + newcount, request - newcount); | 428 | ufs_free_fragments (inode, result + newcount, request - newcount); |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 7f0a0aa63584..433b6f68403a 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -426,7 +426,7 @@ static int | |||
426 | ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 426 | ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) |
427 | { | 427 | { |
428 | loff_t pos = filp->f_pos; | 428 | loff_t pos = filp->f_pos; |
429 | struct inode *inode = filp->f_dentry->d_inode; | 429 | struct inode *inode = filp->f_path.dentry->d_inode; |
430 | struct super_block *sb = inode->i_sb; | 430 | struct super_block *sb = inode->i_sb; |
431 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | 431 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
432 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 432 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index ee1eaa6f4ec2..2fbab0aab688 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -156,36 +156,6 @@ out: | |||
156 | return ret; | 156 | return ret; |
157 | } | 157 | } |
158 | 158 | ||
159 | static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) | ||
160 | { | ||
161 | lock_buffer(bh); | ||
162 | memset(bh->b_data, 0, inode->i_sb->s_blocksize); | ||
163 | set_buffer_uptodate(bh); | ||
164 | mark_buffer_dirty(bh); | ||
165 | unlock_buffer(bh); | ||
166 | if (IS_SYNC(inode)) | ||
167 | sync_dirty_buffer(bh); | ||
168 | } | ||
169 | |||
170 | static struct buffer_head * | ||
171 | ufs_clear_frags(struct inode *inode, sector_t beg, | ||
172 | unsigned int n, sector_t want) | ||
173 | { | ||
174 | struct buffer_head *res = NULL, *bh; | ||
175 | sector_t end = beg + n; | ||
176 | |||
177 | for (; beg < end; ++beg) { | ||
178 | bh = sb_getblk(inode->i_sb, beg); | ||
179 | ufs_clear_frag(inode, bh); | ||
180 | if (want != beg) | ||
181 | brelse(bh); | ||
182 | else | ||
183 | res = bh; | ||
184 | } | ||
185 | BUG_ON(!res); | ||
186 | return res; | ||
187 | } | ||
188 | |||
189 | /** | 159 | /** |
190 | * ufs_inode_getfrag() - allocate new fragment(s) | 160 | * ufs_inode_getfrag() - allocate new fragment(s) |
191 | * @inode - pointer to inode | 161 | * @inode - pointer to inode |
@@ -302,7 +272,7 @@ repeat: | |||
302 | } | 272 | } |
303 | 273 | ||
304 | if (!phys) { | 274 | if (!phys) { |
305 | result = ufs_clear_frags(inode, tmp, required, tmp + blockoff); | 275 | result = sb_getblk(sb, tmp + blockoff); |
306 | } else { | 276 | } else { |
307 | *phys = tmp + blockoff; | 277 | *phys = tmp + blockoff; |
308 | result = NULL; | 278 | result = NULL; |
@@ -403,8 +373,7 @@ repeat: | |||
403 | 373 | ||
404 | 374 | ||
405 | if (!phys) { | 375 | if (!phys) { |
406 | result = ufs_clear_frags(inode, tmp, uspi->s_fpb, | 376 | result = sb_getblk(sb, tmp + blockoff); |
407 | tmp + blockoff); | ||
408 | } else { | 377 | } else { |
409 | *phys = tmp + blockoff; | 378 | *phys = tmp + blockoff; |
410 | *new = 1; | 379 | *new = 1; |
@@ -471,13 +440,13 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head | |||
471 | #define GET_INODE_DATABLOCK(x) \ | 440 | #define GET_INODE_DATABLOCK(x) \ |
472 | ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) | 441 | ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) |
473 | #define GET_INODE_PTR(x) \ | 442 | #define GET_INODE_PTR(x) \ |
474 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, bh_result->b_page) | 443 | ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, NULL) |
475 | #define GET_INDIRECT_DATABLOCK(x) \ | 444 | #define GET_INDIRECT_DATABLOCK(x) \ |
476 | ufs_inode_getblock(inode, bh, x, fragment, \ | 445 | ufs_inode_getblock(inode, bh, x, fragment, \ |
477 | &err, &phys, &new, bh_result->b_page); | 446 | &err, &phys, &new, bh_result->b_page) |
478 | #define GET_INDIRECT_PTR(x) \ | 447 | #define GET_INDIRECT_PTR(x) \ |
479 | ufs_inode_getblock(inode, bh, x, fragment, \ | 448 | ufs_inode_getblock(inode, bh, x, fragment, \ |
480 | &err, NULL, NULL, bh_result->b_page); | 449 | &err, NULL, NULL, NULL) |
481 | 450 | ||
482 | if (ptr < UFS_NDIR_FRAGMENT) { | 451 | if (ptr < UFS_NDIR_FRAGMENT) { |
483 | bh = GET_INODE_DATABLOCK(ptr); | 452 | bh = GET_INODE_DATABLOCK(ptr); |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index ec79e3091d1b..8a8e9382ec09 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -224,7 +224,7 @@ void ufs_error (struct super_block * sb, const char * function, | |||
224 | sb->s_flags |= MS_RDONLY; | 224 | sb->s_flags |= MS_RDONLY; |
225 | } | 225 | } |
226 | va_start (args, fmt); | 226 | va_start (args, fmt); |
227 | vsprintf (error_buf, fmt, args); | 227 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
228 | va_end (args); | 228 | va_end (args); |
229 | switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) { | 229 | switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) { |
230 | case UFS_MOUNT_ONERROR_PANIC: | 230 | case UFS_MOUNT_ONERROR_PANIC: |
@@ -255,7 +255,7 @@ void ufs_panic (struct super_block * sb, const char * function, | |||
255 | sb->s_dirt = 1; | 255 | sb->s_dirt = 1; |
256 | } | 256 | } |
257 | va_start (args, fmt); | 257 | va_start (args, fmt); |
258 | vsprintf (error_buf, fmt, args); | 258 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
259 | va_end (args); | 259 | va_end (args); |
260 | sb->s_flags |= MS_RDONLY; | 260 | sb->s_flags |= MS_RDONLY; |
261 | printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", | 261 | printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", |
@@ -268,7 +268,7 @@ void ufs_warning (struct super_block * sb, const char * function, | |||
268 | va_list args; | 268 | va_list args; |
269 | 269 | ||
270 | va_start (args, fmt); | 270 | va_start (args, fmt); |
271 | vsprintf (error_buf, fmt, args); | 271 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
272 | va_end (args); | 272 | va_end (args); |
273 | printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n", | 273 | printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n", |
274 | sb->s_id, function, error_buf); | 274 | sb->s_id, function, error_buf); |
@@ -1204,12 +1204,12 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1204 | return 0; | 1204 | return 0; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | static kmem_cache_t * ufs_inode_cachep; | 1207 | static struct kmem_cache * ufs_inode_cachep; |
1208 | 1208 | ||
1209 | static struct inode *ufs_alloc_inode(struct super_block *sb) | 1209 | static struct inode *ufs_alloc_inode(struct super_block *sb) |
1210 | { | 1210 | { |
1211 | struct ufs_inode_info *ei; | 1211 | struct ufs_inode_info *ei; |
1212 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, SLAB_KERNEL); | 1212 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_KERNEL); |
1213 | if (!ei) | 1213 | if (!ei) |
1214 | return NULL; | 1214 | return NULL; |
1215 | ei->vfs_inode.i_version = 1; | 1215 | ei->vfs_inode.i_version = 1; |
@@ -1221,7 +1221,7 @@ static void ufs_destroy_inode(struct inode *inode) | |||
1221 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); | 1221 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 1224 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
1225 | { | 1225 | { |
1226 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; | 1226 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; |
1227 | 1227 | ||
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 28fce6c239b5..7dd12bb1d62b 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -299,7 +299,7 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, | |||
299 | 299 | ||
300 | #define ubh_get_addr16(ubh,begin) \ | 300 | #define ubh_get_addr16(ubh,begin) \ |
301 | (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ | 301 | (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ |
302 | ((begin) & (uspi->fsize>>1) - 1))) | 302 | ((begin) & ((uspi->fsize>>1) - 1))) |
303 | 303 | ||
304 | #define ubh_get_addr32(ubh,begin) \ | 304 | #define ubh_get_addr32(ubh,begin) \ |
305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ | 305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ |
diff --git a/fs/utimes.c b/fs/utimes.c index 1bcd852fc4a9..99cf2cb11fec 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/fs.h> | 2 | #include <linux/fs.h> |
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <linux/namei.h> | 4 | #include <linux/namei.h> |
5 | #include <linux/sched.h> | ||
5 | #include <linux/utime.h> | 6 | #include <linux/utime.h> |
6 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
7 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
diff --git a/fs/xattr.c b/fs/xattr.c index 0901bdc2ce24..38646132ab0e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -268,7 +268,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, | |||
268 | f = fget(fd); | 268 | f = fget(fd); |
269 | if (!f) | 269 | if (!f) |
270 | return error; | 270 | return error; |
271 | dentry = f->f_dentry; | 271 | dentry = f->f_path.dentry; |
272 | audit_inode(NULL, dentry->d_inode); | 272 | audit_inode(NULL, dentry->d_inode); |
273 | error = setxattr(dentry, name, value, size, flags); | 273 | error = setxattr(dentry, name, value, size, flags); |
274 | fput(f); | 274 | fput(f); |
@@ -351,7 +351,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size) | |||
351 | f = fget(fd); | 351 | f = fget(fd); |
352 | if (!f) | 352 | if (!f) |
353 | return error; | 353 | return error; |
354 | error = getxattr(f->f_dentry, name, value, size); | 354 | error = getxattr(f->f_path.dentry, name, value, size); |
355 | fput(f); | 355 | fput(f); |
356 | return error; | 356 | return error; |
357 | } | 357 | } |
@@ -423,7 +423,7 @@ sys_flistxattr(int fd, char __user *list, size_t size) | |||
423 | f = fget(fd); | 423 | f = fget(fd); |
424 | if (!f) | 424 | if (!f) |
425 | return error; | 425 | return error; |
426 | error = listxattr(f->f_dentry, list, size); | 426 | error = listxattr(f->f_path.dentry, list, size); |
427 | fput(f); | 427 | fput(f); |
428 | return error; | 428 | return error; |
429 | } | 429 | } |
@@ -484,7 +484,7 @@ sys_fremovexattr(int fd, char __user *name) | |||
484 | f = fget(fd); | 484 | f = fget(fd); |
485 | if (!f) | 485 | if (!f) |
486 | return error; | 486 | return error; |
487 | dentry = f->f_dentry; | 487 | dentry = f->f_path.dentry; |
488 | audit_inode(NULL, dentry->d_inode); | 488 | audit_inode(NULL, dentry->d_inode); |
489 | error = removexattr(dentry, name); | 489 | error = removexattr(dentry, name); |
490 | fput(f); | 490 | fput(f); |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 09360cf1e1f2..7b54461695e2 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -149,9 +149,10 @@ xfs_destroy_ioend( | |||
149 | */ | 149 | */ |
150 | STATIC void | 150 | STATIC void |
151 | xfs_end_bio_delalloc( | 151 | xfs_end_bio_delalloc( |
152 | void *data) | 152 | struct work_struct *work) |
153 | { | 153 | { |
154 | xfs_ioend_t *ioend = data; | 154 | xfs_ioend_t *ioend = |
155 | container_of(work, xfs_ioend_t, io_work); | ||
155 | 156 | ||
156 | xfs_destroy_ioend(ioend); | 157 | xfs_destroy_ioend(ioend); |
157 | } | 158 | } |
@@ -161,9 +162,10 @@ xfs_end_bio_delalloc( | |||
161 | */ | 162 | */ |
162 | STATIC void | 163 | STATIC void |
163 | xfs_end_bio_written( | 164 | xfs_end_bio_written( |
164 | void *data) | 165 | struct work_struct *work) |
165 | { | 166 | { |
166 | xfs_ioend_t *ioend = data; | 167 | xfs_ioend_t *ioend = |
168 | container_of(work, xfs_ioend_t, io_work); | ||
167 | 169 | ||
168 | xfs_destroy_ioend(ioend); | 170 | xfs_destroy_ioend(ioend); |
169 | } | 171 | } |
@@ -176,9 +178,10 @@ xfs_end_bio_written( | |||
176 | */ | 178 | */ |
177 | STATIC void | 179 | STATIC void |
178 | xfs_end_bio_unwritten( | 180 | xfs_end_bio_unwritten( |
179 | void *data) | 181 | struct work_struct *work) |
180 | { | 182 | { |
181 | xfs_ioend_t *ioend = data; | 183 | xfs_ioend_t *ioend = |
184 | container_of(work, xfs_ioend_t, io_work); | ||
182 | bhv_vnode_t *vp = ioend->io_vnode; | 185 | bhv_vnode_t *vp = ioend->io_vnode; |
183 | xfs_off_t offset = ioend->io_offset; | 186 | xfs_off_t offset = ioend->io_offset; |
184 | size_t size = ioend->io_size; | 187 | size_t size = ioend->io_size; |
@@ -220,11 +223,11 @@ xfs_alloc_ioend( | |||
220 | ioend->io_size = 0; | 223 | ioend->io_size = 0; |
221 | 224 | ||
222 | if (type == IOMAP_UNWRITTEN) | 225 | if (type == IOMAP_UNWRITTEN) |
223 | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend); | 226 | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); |
224 | else if (type == IOMAP_DELAY) | 227 | else if (type == IOMAP_DELAY) |
225 | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc, ioend); | 228 | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); |
226 | else | 229 | else |
227 | INIT_WORK(&ioend->io_work, xfs_end_bio_written, ioend); | 230 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); |
228 | 231 | ||
229 | return ioend; | 232 | return ioend; |
230 | } | 233 | } |
@@ -338,9 +341,9 @@ xfs_start_page_writeback( | |||
338 | { | 341 | { |
339 | ASSERT(PageLocked(page)); | 342 | ASSERT(PageLocked(page)); |
340 | ASSERT(!PageWriteback(page)); | 343 | ASSERT(!PageWriteback(page)); |
341 | set_page_writeback(page); | ||
342 | if (clear_dirty) | 344 | if (clear_dirty) |
343 | clear_page_dirty(page); | 345 | clear_page_dirty_for_io(page); |
346 | set_page_writeback(page); | ||
344 | unlock_page(page); | 347 | unlock_page(page); |
345 | if (!buffers) { | 348 | if (!buffers) { |
346 | end_page_writeback(page); | 349 | end_page_writeback(page); |
@@ -1403,7 +1406,7 @@ xfs_vm_direct_IO( | |||
1403 | xfs_end_io_direct); | 1406 | xfs_end_io_direct); |
1404 | } | 1407 | } |
1405 | 1408 | ||
1406 | if (unlikely(ret <= 0 && iocb->private)) | 1409 | if (unlikely(ret != -EIOCBQUEUED && iocb->private)) |
1407 | xfs_destroy_ioend(iocb->private); | 1410 | xfs_destroy_ioend(iocb->private); |
1408 | return ret; | 1411 | return ret; |
1409 | } | 1412 | } |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index d3382843698e..4fb01ffdfd1a 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
33 | #include <linux/migrate.h> | 33 | #include <linux/migrate.h> |
34 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
35 | #include <linux/freezer.h> | ||
35 | 36 | ||
36 | STATIC kmem_zone_t *xfs_buf_zone; | 37 | STATIC kmem_zone_t *xfs_buf_zone; |
37 | STATIC kmem_shaker_t xfs_buf_shake; | 38 | STATIC kmem_shaker_t xfs_buf_shake; |
@@ -994,9 +995,10 @@ xfs_buf_wait_unpin( | |||
994 | 995 | ||
995 | STATIC void | 996 | STATIC void |
996 | xfs_buf_iodone_work( | 997 | xfs_buf_iodone_work( |
997 | void *v) | 998 | struct work_struct *work) |
998 | { | 999 | { |
999 | xfs_buf_t *bp = (xfs_buf_t *)v; | 1000 | xfs_buf_t *bp = |
1001 | container_of(work, xfs_buf_t, b_iodone_work); | ||
1000 | 1002 | ||
1001 | if (bp->b_iodone) | 1003 | if (bp->b_iodone) |
1002 | (*(bp->b_iodone))(bp); | 1004 | (*(bp->b_iodone))(bp); |
@@ -1017,10 +1019,10 @@ xfs_buf_ioend( | |||
1017 | 1019 | ||
1018 | if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { | 1020 | if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { |
1019 | if (schedule) { | 1021 | if (schedule) { |
1020 | INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp); | 1022 | INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); |
1021 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); | 1023 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); |
1022 | } else { | 1024 | } else { |
1023 | xfs_buf_iodone_work(bp); | 1025 | xfs_buf_iodone_work(&bp->b_iodone_work); |
1024 | } | 1026 | } |
1025 | } else { | 1027 | } else { |
1026 | up(&bp->b_iodonesema); | 1028 | up(&bp->b_iodonesema); |
@@ -1825,11 +1827,11 @@ xfs_buf_init(void) | |||
1825 | if (!xfs_buf_zone) | 1827 | if (!xfs_buf_zone) |
1826 | goto out_free_trace_buf; | 1828 | goto out_free_trace_buf; |
1827 | 1829 | ||
1828 | xfslogd_workqueue = create_workqueue("xfslogd"); | 1830 | xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); |
1829 | if (!xfslogd_workqueue) | 1831 | if (!xfslogd_workqueue) |
1830 | goto out_free_buf_zone; | 1832 | goto out_free_buf_zone; |
1831 | 1833 | ||
1832 | xfsdatad_workqueue = create_workqueue("xfsdatad"); | 1834 | xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); |
1833 | if (!xfsdatad_workqueue) | 1835 | if (!xfsdatad_workqueue) |
1834 | goto out_destroy_xfslogd_workqueue; | 1836 | goto out_destroy_xfslogd_workqueue; |
1835 | 1837 | ||
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index d93d8dd1958d..d26f5cd2ba70 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -55,7 +55,7 @@ __xfs_file_read( | |||
55 | loff_t pos) | 55 | loff_t pos) |
56 | { | 56 | { |
57 | struct file *file = iocb->ki_filp; | 57 | struct file *file = iocb->ki_filp; |
58 | bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); | 58 | bhv_vnode_t *vp = vn_from_inode(file->f_path.dentry->d_inode); |
59 | 59 | ||
60 | BUG_ON(iocb->ki_pos != pos); | 60 | BUG_ON(iocb->ki_pos != pos); |
61 | if (unlikely(file->f_flags & O_DIRECT)) | 61 | if (unlikely(file->f_flags & O_DIRECT)) |
@@ -131,7 +131,7 @@ xfs_file_sendfile( | |||
131 | read_actor_t actor, | 131 | read_actor_t actor, |
132 | void *target) | 132 | void *target) |
133 | { | 133 | { |
134 | return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode), | 134 | return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode), |
135 | filp, pos, 0, count, actor, target, NULL); | 135 | filp, pos, 0, count, actor, target, NULL); |
136 | } | 136 | } |
137 | 137 | ||
@@ -143,7 +143,7 @@ xfs_file_sendfile_invis( | |||
143 | read_actor_t actor, | 143 | read_actor_t actor, |
144 | void *target) | 144 | void *target) |
145 | { | 145 | { |
146 | return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode), | 146 | return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode), |
147 | filp, pos, IO_INVIS, count, actor, target, NULL); | 147 | filp, pos, IO_INVIS, count, actor, target, NULL); |
148 | } | 148 | } |
149 | 149 | ||
@@ -155,7 +155,7 @@ xfs_file_splice_read( | |||
155 | size_t len, | 155 | size_t len, |
156 | unsigned int flags) | 156 | unsigned int flags) |
157 | { | 157 | { |
158 | return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode), | 158 | return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), |
159 | infilp, ppos, pipe, len, flags, 0, NULL); | 159 | infilp, ppos, pipe, len, flags, 0, NULL); |
160 | } | 160 | } |
161 | 161 | ||
@@ -167,7 +167,7 @@ xfs_file_splice_read_invis( | |||
167 | size_t len, | 167 | size_t len, |
168 | unsigned int flags) | 168 | unsigned int flags) |
169 | { | 169 | { |
170 | return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode), | 170 | return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), |
171 | infilp, ppos, pipe, len, flags, IO_INVIS, | 171 | infilp, ppos, pipe, len, flags, IO_INVIS, |
172 | NULL); | 172 | NULL); |
173 | } | 173 | } |
@@ -180,7 +180,7 @@ xfs_file_splice_write( | |||
180 | size_t len, | 180 | size_t len, |
181 | unsigned int flags) | 181 | unsigned int flags) |
182 | { | 182 | { |
183 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode), | 183 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), |
184 | pipe, outfilp, ppos, len, flags, 0, NULL); | 184 | pipe, outfilp, ppos, len, flags, 0, NULL); |
185 | } | 185 | } |
186 | 186 | ||
@@ -192,7 +192,7 @@ xfs_file_splice_write_invis( | |||
192 | size_t len, | 192 | size_t len, |
193 | unsigned int flags) | 193 | unsigned int flags) |
194 | { | 194 | { |
195 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode), | 195 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), |
196 | pipe, outfilp, ppos, len, flags, IO_INVIS, | 196 | pipe, outfilp, ppos, len, flags, IO_INVIS, |
197 | NULL); | 197 | NULL); |
198 | } | 198 | } |
@@ -212,7 +212,7 @@ xfs_file_close( | |||
212 | struct file *filp, | 212 | struct file *filp, |
213 | fl_owner_t id) | 213 | fl_owner_t id) |
214 | { | 214 | { |
215 | return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0, | 215 | return -bhv_vop_close(vn_from_inode(filp->f_path.dentry->d_inode), 0, |
216 | file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL); | 216 | file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL); |
217 | } | 217 | } |
218 | 218 | ||
@@ -251,7 +251,7 @@ xfs_vm_nopage( | |||
251 | unsigned long address, | 251 | unsigned long address, |
252 | int *type) | 252 | int *type) |
253 | { | 253 | { |
254 | struct inode *inode = area->vm_file->f_dentry->d_inode; | 254 | struct inode *inode = area->vm_file->f_path.dentry->d_inode; |
255 | bhv_vnode_t *vp = vn_from_inode(inode); | 255 | bhv_vnode_t *vp = vn_from_inode(inode); |
256 | 256 | ||
257 | ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); | 257 | ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); |
@@ -268,7 +268,7 @@ xfs_file_readdir( | |||
268 | filldir_t filldir) | 268 | filldir_t filldir) |
269 | { | 269 | { |
270 | int error = 0; | 270 | int error = 0; |
271 | bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | 271 | bhv_vnode_t *vp = vn_from_inode(filp->f_path.dentry->d_inode); |
272 | uio_t uio; | 272 | uio_t uio; |
273 | iovec_t iov; | 273 | iovec_t iov; |
274 | int eof = 0; | 274 | int eof = 0; |
@@ -345,7 +345,7 @@ xfs_file_mmap( | |||
345 | vma->vm_ops = &xfs_file_vm_ops; | 345 | vma->vm_ops = &xfs_file_vm_ops; |
346 | 346 | ||
347 | #ifdef CONFIG_XFS_DMAPI | 347 | #ifdef CONFIG_XFS_DMAPI |
348 | if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) | 348 | if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) |
349 | vma->vm_ops = &xfs_dmapi_file_vm_ops; | 349 | vma->vm_ops = &xfs_dmapi_file_vm_ops; |
350 | #endif /* CONFIG_XFS_DMAPI */ | 350 | #endif /* CONFIG_XFS_DMAPI */ |
351 | 351 | ||
@@ -360,7 +360,7 @@ xfs_file_ioctl( | |||
360 | unsigned long p) | 360 | unsigned long p) |
361 | { | 361 | { |
362 | int error; | 362 | int error; |
363 | struct inode *inode = filp->f_dentry->d_inode; | 363 | struct inode *inode = filp->f_path.dentry->d_inode; |
364 | bhv_vnode_t *vp = vn_from_inode(inode); | 364 | bhv_vnode_t *vp = vn_from_inode(inode); |
365 | 365 | ||
366 | error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p); | 366 | error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p); |
@@ -382,7 +382,7 @@ xfs_file_ioctl_invis( | |||
382 | unsigned long p) | 382 | unsigned long p) |
383 | { | 383 | { |
384 | int error; | 384 | int error; |
385 | struct inode *inode = filp->f_dentry->d_inode; | 385 | struct inode *inode = filp->f_path.dentry->d_inode; |
386 | bhv_vnode_t *vp = vn_from_inode(inode); | 386 | bhv_vnode_t *vp = vn_from_inode(inode); |
387 | 387 | ||
388 | error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p); | 388 | error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p); |
@@ -404,7 +404,7 @@ xfs_vm_mprotect( | |||
404 | struct vm_area_struct *vma, | 404 | struct vm_area_struct *vma, |
405 | unsigned int newflags) | 405 | unsigned int newflags) |
406 | { | 406 | { |
407 | bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); | 407 | bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_path.dentry->d_inode); |
408 | int error = 0; | 408 | int error = 0; |
409 | 409 | ||
410 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { | 410 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 74d094829a4d..f011c9cd0d62 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -107,9 +107,9 @@ xfs_find_handle( | |||
107 | if (!file) | 107 | if (!file) |
108 | return -EBADF; | 108 | return -EBADF; |
109 | 109 | ||
110 | ASSERT(file->f_dentry); | 110 | ASSERT(file->f_path.dentry); |
111 | ASSERT(file->f_dentry->d_inode); | 111 | ASSERT(file->f_path.dentry->d_inode); |
112 | inode = igrab(file->f_dentry->d_inode); | 112 | inode = igrab(file->f_path.dentry->d_inode); |
113 | fput(file); | 113 | fput(file); |
114 | break; | 114 | break; |
115 | } | 115 | } |
@@ -333,10 +333,10 @@ xfs_open_by_handle( | |||
333 | } | 333 | } |
334 | 334 | ||
335 | /* Ensure umount returns EBUSY on umounts while this file is open. */ | 335 | /* Ensure umount returns EBUSY on umounts while this file is open. */ |
336 | mntget(parfilp->f_vfsmnt); | 336 | mntget(parfilp->f_path.mnt); |
337 | 337 | ||
338 | /* Create file pointer. */ | 338 | /* Create file pointer. */ |
339 | filp = dentry_open(dentry, parfilp->f_vfsmnt, hreq.oflags); | 339 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); |
340 | if (IS_ERR(filp)) { | 340 | if (IS_ERR(filp)) { |
341 | put_unused_fd(new_fd); | 341 | put_unused_fd(new_fd); |
342 | return -XFS_ERROR(-PTR_ERR(filp)); | 342 | return -XFS_ERROR(-PTR_ERR(filp)); |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 270db0f3861d..b83cebc165f1 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
@@ -112,7 +112,7 @@ xfs_compat_ioctl( | |||
112 | unsigned cmd, | 112 | unsigned cmd, |
113 | unsigned long arg) | 113 | unsigned long arg) |
114 | { | 114 | { |
115 | struct inode *inode = file->f_dentry->d_inode; | 115 | struct inode *inode = file->f_path.dentry->d_inode; |
116 | bhv_vnode_t *vp = vn_from_inode(inode); | 116 | bhv_vnode_t *vp = vn_from_inode(inode); |
117 | int error; | 117 | int error; |
118 | 118 | ||
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index fa842f1c9fa2..65e79b471d49 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -805,7 +805,7 @@ start: | |||
805 | !capable(CAP_FSETID)) { | 805 | !capable(CAP_FSETID)) { |
806 | error = xfs_write_clear_setuid(xip); | 806 | error = xfs_write_clear_setuid(xip); |
807 | if (likely(!error)) | 807 | if (likely(!error)) |
808 | error = -remove_suid(file->f_dentry); | 808 | error = -remove_suid(file->f_path.dentry); |
809 | if (unlikely(error)) { | 809 | if (unlikely(error)) { |
810 | xfs_iunlock(xip, iolock); | 810 | xfs_iunlock(xip, iolock); |
811 | goto out_unlock_mutex; | 811 | goto out_unlock_mutex; |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index de05abbbe7fd..b93265b7c79c 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/mempool.h> | 56 | #include <linux/mempool.h> |
57 | #include <linux/writeback.h> | 57 | #include <linux/writeback.h> |
58 | #include <linux/kthread.h> | 58 | #include <linux/kthread.h> |
59 | #include <linux/freezer.h> | ||
59 | 60 | ||
60 | STATIC struct quotactl_ops xfs_quotactl_operations; | 61 | STATIC struct quotactl_ops xfs_quotactl_operations; |
61 | STATIC struct super_operations xfs_super_operations; | 62 | STATIC struct super_operations xfs_super_operations; |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 80562b60fb95..50d0faea371d 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -71,7 +71,7 @@ xfs_swapext( | |||
71 | 71 | ||
72 | /* Pull information for the target fd */ | 72 | /* Pull information for the target fd */ |
73 | if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) || | 73 | if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) || |
74 | ((vp = vn_from_inode(fp->f_dentry->d_inode)) == NULL)) { | 74 | ((vp = vn_from_inode(fp->f_path.dentry->d_inode)) == NULL)) { |
75 | error = XFS_ERROR(EINVAL); | 75 | error = XFS_ERROR(EINVAL); |
76 | goto error0; | 76 | goto error0; |
77 | } | 77 | } |
@@ -83,7 +83,7 @@ xfs_swapext( | |||
83 | } | 83 | } |
84 | 84 | ||
85 | if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) || | 85 | if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) || |
86 | ((tvp = vn_from_inode(tfp->f_dentry->d_inode)) == NULL)) { | 86 | ((tvp = vn_from_inode(tfp->f_path.dentry->d_inode)) == NULL)) { |
87 | error = XFS_ERROR(EINVAL); | 87 | error = XFS_ERROR(EINVAL); |
88 | goto error0; | 88 | goto error0; |
89 | } | 89 | } |