diff options
Diffstat (limited to 'fs')
45 files changed, 370 insertions, 144 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 5c5bc8480070..f8b86e92cd66 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -238,6 +238,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
238 | return ERR_PTR(-ENOMEM); | 238 | return ERR_PTR(-ENOMEM); |
239 | } | 239 | } |
240 | 240 | ||
241 | rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY); | ||
242 | if (rc) { | ||
243 | __putname(v9ses->aname); | ||
244 | __putname(v9ses->uname); | ||
245 | return ERR_PTR(rc); | ||
246 | } | ||
247 | |||
241 | spin_lock(&v9fs_sessionlist_lock); | 248 | spin_lock(&v9fs_sessionlist_lock); |
242 | list_add(&v9ses->slist, &v9fs_sessionlist); | 249 | list_add(&v9ses->slist, &v9fs_sessionlist); |
243 | spin_unlock(&v9fs_sessionlist_lock); | 250 | spin_unlock(&v9fs_sessionlist_lock); |
@@ -301,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
301 | return fid; | 308 | return fid; |
302 | 309 | ||
303 | error: | 310 | error: |
311 | bdi_destroy(&v9ses->bdi); | ||
304 | return ERR_PTR(retval); | 312 | return ERR_PTR(retval); |
305 | } | 313 | } |
306 | 314 | ||
@@ -326,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
326 | __putname(v9ses->uname); | 334 | __putname(v9ses->uname); |
327 | __putname(v9ses->aname); | 335 | __putname(v9ses->aname); |
328 | 336 | ||
337 | bdi_destroy(&v9ses->bdi); | ||
338 | |||
329 | spin_lock(&v9fs_sessionlist_lock); | 339 | spin_lock(&v9fs_sessionlist_lock); |
330 | list_del(&v9ses->slist); | 340 | list_del(&v9ses->slist); |
331 | spin_unlock(&v9fs_sessionlist_lock); | 341 | spin_unlock(&v9fs_sessionlist_lock); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index a0a8d3dd1361..bec4d0bcb458 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -20,6 +20,7 @@ | |||
20 | * Boston, MA 02111-1301 USA | 20 | * Boston, MA 02111-1301 USA |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/backing-dev.h> | ||
23 | 24 | ||
24 | /** | 25 | /** |
25 | * enum p9_session_flags - option flags for each 9P session | 26 | * enum p9_session_flags - option flags for each 9P session |
@@ -102,6 +103,7 @@ struct v9fs_session_info { | |||
102 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ | 103 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ |
103 | struct p9_client *clnt; /* 9p client */ | 104 | struct p9_client *clnt; /* 9p client */ |
104 | struct list_head slist; /* list of sessions registered with v9fs */ | 105 | struct list_head slist; /* list of sessions registered with v9fs */ |
106 | struct backing_dev_info bdi; | ||
105 | }; | 107 | }; |
106 | 108 | ||
107 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | 109 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 491108bd6e0d..806da5d3b3a0 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -77,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, | |||
77 | sb->s_blocksize = 1 << sb->s_blocksize_bits; | 77 | sb->s_blocksize = 1 << sb->s_blocksize_bits; |
78 | sb->s_magic = V9FS_MAGIC; | 78 | sb->s_magic = V9FS_MAGIC; |
79 | sb->s_op = &v9fs_super_ops; | 79 | sb->s_op = &v9fs_super_ops; |
80 | sb->s_bdi = &v9ses->bdi; | ||
80 | 81 | ||
81 | sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | | 82 | sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | |
82 | MS_NOATIME; | 83 | MS_NOATIME; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index c54dad4e6063..a10f2582844f 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/fscache.h> | 21 | #include <linux/fscache.h> |
22 | #include <linux/backing-dev.h> | ||
22 | 23 | ||
23 | #include "afs.h" | 24 | #include "afs.h" |
24 | #include "afs_vl.h" | 25 | #include "afs_vl.h" |
@@ -313,6 +314,7 @@ struct afs_volume { | |||
313 | unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ | 314 | unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ |
314 | struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ | 315 | struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ |
315 | struct rw_semaphore server_sem; /* lock for accessing current server */ | 316 | struct rw_semaphore server_sem; /* lock for accessing current server */ |
317 | struct backing_dev_info bdi; | ||
316 | }; | 318 | }; |
317 | 319 | ||
318 | /* | 320 | /* |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 14f6431598ad..e932e5a3a0c1 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
311 | sb->s_magic = AFS_FS_MAGIC; | 311 | sb->s_magic = AFS_FS_MAGIC; |
312 | sb->s_op = &afs_super_ops; | 312 | sb->s_op = &afs_super_ops; |
313 | sb->s_fs_info = as; | 313 | sb->s_fs_info = as; |
314 | sb->s_bdi = &as->volume->bdi; | ||
314 | 315 | ||
315 | /* allocate the root inode and dentry */ | 316 | /* allocate the root inode and dentry */ |
316 | fid.vid = as->volume->vid; | 317 | fid.vid = as->volume->vid; |
diff --git a/fs/afs/volume.c b/fs/afs/volume.c index a353e69e2391..401eeb21869f 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c | |||
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) | |||
106 | volume->cell = params->cell; | 106 | volume->cell = params->cell; |
107 | volume->vid = vlocation->vldb.vid[params->type]; | 107 | volume->vid = vlocation->vldb.vid[params->type]; |
108 | 108 | ||
109 | ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY); | ||
110 | if (ret) | ||
111 | goto error_bdi; | ||
112 | |||
109 | init_rwsem(&volume->server_sem); | 113 | init_rwsem(&volume->server_sem); |
110 | 114 | ||
111 | /* look up all the applicable server records */ | 115 | /* look up all the applicable server records */ |
@@ -151,6 +155,8 @@ error: | |||
151 | return ERR_PTR(ret); | 155 | return ERR_PTR(ret); |
152 | 156 | ||
153 | error_discard: | 157 | error_discard: |
158 | bdi_destroy(&volume->bdi); | ||
159 | error_bdi: | ||
154 | up_write(¶ms->cell->vl_sem); | 160 | up_write(¶ms->cell->vl_sem); |
155 | 161 | ||
156 | for (loop = volume->nservers - 1; loop >= 0; loop--) | 162 | for (loop = volume->nservers - 1; loop >= 0; loop--) |
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume) | |||
200 | for (loop = volume->nservers - 1; loop >= 0; loop--) | 206 | for (loop = volume->nservers - 1; loop >= 0; loop--) |
201 | afs_put_server(volume->servers[loop]); | 207 | afs_put_server(volume->servers[loop]); |
202 | 208 | ||
209 | bdi_destroy(&volume->bdi); | ||
203 | kfree(volume); | 210 | kfree(volume); |
204 | 211 | ||
205 | _leave(" [destroyed]"); | 212 | _leave(" [destroyed]"); |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 7ab23e006e4c..2c5f9a0e5d72 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1005,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( | |||
1005 | } | 1005 | } |
1006 | } else if (!mm->start_data) { | 1006 | } else if (!mm->start_data) { |
1007 | mm->start_data = seg->addr; | 1007 | mm->start_data = seg->addr; |
1008 | #ifndef CONFIG_MMU | ||
1009 | mm->end_data = seg->addr + phdr->p_memsz; | 1008 | mm->end_data = seg->addr + phdr->p_memsz; |
1010 | #endif | ||
1011 | } | 1009 | } |
1012 | |||
1013 | #ifdef CONFIG_MMU | ||
1014 | if (seg->addr + phdr->p_memsz > mm->end_data) | ||
1015 | mm->end_data = seg->addr + phdr->p_memsz; | ||
1016 | #endif | ||
1017 | } | 1010 | } |
1018 | 1011 | ||
1019 | seg++; | 1012 | seg++; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 2a6d0193f139..6dcee88c2e5d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -406,16 +406,23 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
406 | 406 | ||
407 | int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) | 407 | int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) |
408 | { | 408 | { |
409 | struct block_device *bdev = I_BDEV(filp->f_mapping->host); | 409 | struct inode *bd_inode = filp->f_mapping->host; |
410 | struct block_device *bdev = I_BDEV(bd_inode); | ||
410 | int error; | 411 | int error; |
411 | 412 | ||
412 | error = sync_blockdev(bdev); | 413 | /* |
413 | if (error) | 414 | * There is no need to serialise calls to blkdev_issue_flush with |
414 | return error; | 415 | * i_mutex and doing so causes performance issues with concurrent |
415 | 416 | * O_SYNC writers to a block device. | |
417 | */ | ||
418 | mutex_unlock(&bd_inode->i_mutex); | ||
419 | |||
416 | error = blkdev_issue_flush(bdev, NULL); | 420 | error = blkdev_issue_flush(bdev, NULL); |
417 | if (error == -EOPNOTSUPP) | 421 | if (error == -EOPNOTSUPP) |
418 | error = 0; | 422 | error = 0; |
423 | |||
424 | mutex_lock(&bd_inode->i_mutex); | ||
425 | |||
419 | return error; | 426 | return error; |
420 | } | 427 | } |
421 | EXPORT_SYMBOL(blkdev_fsync); | 428 | EXPORT_SYMBOL(blkdev_fsync); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e7b8f2c89ccb..feca04197d02 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -44,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops; | |||
44 | static void end_workqueue_fn(struct btrfs_work *work); | 44 | static void end_workqueue_fn(struct btrfs_work *work); |
45 | static void free_fs_root(struct btrfs_root *root); | 45 | static void free_fs_root(struct btrfs_root *root); |
46 | 46 | ||
47 | static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); | ||
48 | |||
49 | /* | 47 | /* |
50 | * end_io_wq structs are used to do processing in task context when an IO is | 48 | * end_io_wq structs are used to do processing in task context when an IO is |
51 | * complete. This is used during reads to verify checksums, and it is used | 49 | * complete. This is used during reads to verify checksums, and it is used |
@@ -1375,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | |||
1375 | { | 1373 | { |
1376 | int err; | 1374 | int err; |
1377 | 1375 | ||
1378 | bdi->name = "btrfs"; | ||
1379 | bdi->capabilities = BDI_CAP_MAP_COPY; | 1376 | bdi->capabilities = BDI_CAP_MAP_COPY; |
1380 | err = bdi_init(bdi); | 1377 | err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY); |
1381 | if (err) | 1378 | if (err) |
1382 | return err; | 1379 | return err; |
1383 | 1380 | ||
1384 | err = bdi_register(bdi, NULL, "btrfs-%d", | ||
1385 | atomic_inc_return(&btrfs_bdi_num)); | ||
1386 | if (err) { | ||
1387 | bdi_destroy(bdi); | ||
1388 | return err; | ||
1389 | } | ||
1390 | |||
1391 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1381 | bdi->ra_pages = default_backing_dev_info.ra_pages; |
1392 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | 1382 | bdi->unplug_io_fn = btrfs_unplug_io_fn; |
1393 | bdi->unplug_io_data = info; | 1383 | bdi->unplug_io_data = info; |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 4797787c6a44..246a167cb913 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef _CIFS_FS_SB_H | 18 | #ifndef _CIFS_FS_SB_H |
19 | #define _CIFS_FS_SB_H | 19 | #define _CIFS_FS_SB_H |
20 | 20 | ||
21 | #include <linux/backing-dev.h> | ||
22 | |||
21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ | 23 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ |
22 | #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ | 24 | #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ |
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 25 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
@@ -50,5 +52,6 @@ struct cifs_sb_info { | |||
50 | #ifdef CONFIG_CIFS_DFS_UPCALL | 52 | #ifdef CONFIG_CIFS_DFS_UPCALL |
51 | char *mountdata; /* mount options received at mount time */ | 53 | char *mountdata; /* mount options received at mount time */ |
52 | #endif | 54 | #endif |
55 | struct backing_dev_info bdi; | ||
53 | }; | 56 | }; |
54 | #endif /* _CIFS_FS_SB_H */ | 57 | #endif /* _CIFS_FS_SB_H */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ded66be6597c..ad235d604a0b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data, | |||
103 | if (cifs_sb == NULL) | 103 | if (cifs_sb == NULL) |
104 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | 105 | ||
106 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | ||
107 | if (rc) { | ||
108 | kfree(cifs_sb); | ||
109 | return rc; | ||
110 | } | ||
111 | |||
106 | #ifdef CONFIG_CIFS_DFS_UPCALL | 112 | #ifdef CONFIG_CIFS_DFS_UPCALL |
107 | /* copy mount params to sb for use in submounts */ | 113 | /* copy mount params to sb for use in submounts */ |
108 | /* BB: should we move this after the mount so we | 114 | /* BB: should we move this after the mount so we |
@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
115 | int len = strlen(data); | 121 | int len = strlen(data); |
116 | cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); | 122 | cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); |
117 | if (cifs_sb->mountdata == NULL) { | 123 | if (cifs_sb->mountdata == NULL) { |
124 | bdi_destroy(&cifs_sb->bdi); | ||
118 | kfree(sb->s_fs_info); | 125 | kfree(sb->s_fs_info); |
119 | sb->s_fs_info = NULL; | 126 | sb->s_fs_info = NULL; |
120 | return -ENOMEM; | 127 | return -ENOMEM; |
@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
135 | 142 | ||
136 | sb->s_magic = CIFS_MAGIC_NUMBER; | 143 | sb->s_magic = CIFS_MAGIC_NUMBER; |
137 | sb->s_op = &cifs_super_ops; | 144 | sb->s_op = &cifs_super_ops; |
145 | sb->s_bdi = &cifs_sb->bdi; | ||
138 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) | 146 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) |
139 | sb->s_blocksize = | 147 | sb->s_blocksize = |
140 | cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ | 148 | cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ |
@@ -183,6 +191,7 @@ out_mount_failed: | |||
183 | } | 191 | } |
184 | #endif | 192 | #endif |
185 | unload_nls(cifs_sb->local_nls); | 193 | unload_nls(cifs_sb->local_nls); |
194 | bdi_destroy(&cifs_sb->bdi); | ||
186 | kfree(cifs_sb); | 195 | kfree(cifs_sb); |
187 | } | 196 | } |
188 | return rc; | 197 | return rc; |
@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb) | |||
214 | #endif | 223 | #endif |
215 | 224 | ||
216 | unload_nls(cifs_sb->local_nls); | 225 | unload_nls(cifs_sb->local_nls); |
226 | bdi_destroy(&cifs_sb->bdi); | ||
217 | kfree(cifs_sb); | 227 | kfree(cifs_sb); |
218 | 228 | ||
219 | unlock_kernel(); | 229 | unlock_kernel(); |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index a1695dcadd99..d97f9935a028 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -167,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
167 | return -EBUSY; | 167 | return -EBUSY; |
168 | } | 168 | } |
169 | 169 | ||
170 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); | ||
171 | if (error) | ||
172 | goto bdi_err; | ||
173 | |||
170 | vc->vc_sb = sb; | 174 | vc->vc_sb = sb; |
171 | 175 | ||
172 | sb->s_fs_info = vc; | 176 | sb->s_fs_info = vc; |
@@ -175,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
175 | sb->s_blocksize_bits = 12; | 179 | sb->s_blocksize_bits = 12; |
176 | sb->s_magic = CODA_SUPER_MAGIC; | 180 | sb->s_magic = CODA_SUPER_MAGIC; |
177 | sb->s_op = &coda_super_operations; | 181 | sb->s_op = &coda_super_operations; |
182 | sb->s_bdi = &vc->bdi; | ||
178 | 183 | ||
179 | /* get root fid from Venus: this needs the root inode */ | 184 | /* get root fid from Venus: this needs the root inode */ |
180 | error = venus_rootfid(sb, &fid); | 185 | error = venus_rootfid(sb, &fid); |
@@ -200,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
200 | return 0; | 205 | return 0; |
201 | 206 | ||
202 | error: | 207 | error: |
208 | bdi_destroy(&vc->bdi); | ||
209 | bdi_err: | ||
203 | if (root) | 210 | if (root) |
204 | iput(root); | 211 | iput(root); |
205 | if (vc) | 212 | if (vc) |
@@ -210,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
210 | 217 | ||
211 | static void coda_put_super(struct super_block *sb) | 218 | static void coda_put_super(struct super_block *sb) |
212 | { | 219 | { |
220 | bdi_destroy(&coda_vcp(sb)->bdi); | ||
213 | coda_vcp(sb)->vc_sb = NULL; | 221 | coda_vcp(sb)->vc_sb = NULL; |
214 | sb->s_fs_info = NULL; | 222 | sb->s_fs_info = NULL; |
215 | 223 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index c32a1b6a856b..641640dc7ae5 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -102,7 +102,6 @@ | |||
102 | #include <linux/nbd.h> | 102 | #include <linux/nbd.h> |
103 | #include <linux/random.h> | 103 | #include <linux/random.h> |
104 | #include <linux/filter.h> | 104 | #include <linux/filter.h> |
105 | #include <linux/pktcdvd.h> | ||
106 | 105 | ||
107 | #include <linux/hiddev.h> | 106 | #include <linux/hiddev.h> |
108 | 107 | ||
@@ -1126,8 +1125,6 @@ COMPATIBLE_IOCTL(PPGETMODE) | |||
1126 | COMPATIBLE_IOCTL(PPGETPHASE) | 1125 | COMPATIBLE_IOCTL(PPGETPHASE) |
1127 | COMPATIBLE_IOCTL(PPGETFLAGS) | 1126 | COMPATIBLE_IOCTL(PPGETFLAGS) |
1128 | COMPATIBLE_IOCTL(PPSETFLAGS) | 1127 | COMPATIBLE_IOCTL(PPSETFLAGS) |
1129 | /* pktcdvd */ | ||
1130 | COMPATIBLE_IOCTL(PACKET_CTRL_CMD) | ||
1131 | /* Big A */ | 1128 | /* Big A */ |
1132 | /* sparc only */ | 1129 | /* sparc only */ |
1133 | /* Big Q for sound/OSS */ | 1130 | /* Big Q for sound/OSS */ |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index bc7115403f38..bfc2e0f78f00 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | 36 | #include <linux/hash.h> |
37 | #include <linux/nsproxy.h> | 37 | #include <linux/nsproxy.h> |
38 | #include <linux/backing-dev.h> | ||
38 | 39 | ||
39 | /* Version verification for shared data structures w/ userspace */ | 40 | /* Version verification for shared data structures w/ userspace */ |
40 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 41 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat { | |||
393 | struct ecryptfs_sb_info { | 394 | struct ecryptfs_sb_info { |
394 | struct super_block *wsi_sb; | 395 | struct super_block *wsi_sb; |
395 | struct ecryptfs_mount_crypt_stat mount_crypt_stat; | 396 | struct ecryptfs_mount_crypt_stat mount_crypt_stat; |
397 | struct backing_dev_info bdi; | ||
396 | }; | 398 | }; |
397 | 399 | ||
398 | /* file private data. */ | 400 | /* file private data. */ |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index af1a8f01ebac..760983d0f25e 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -497,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache; | |||
497 | static int | 497 | static int |
498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | 498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) |
499 | { | 499 | { |
500 | struct ecryptfs_sb_info *esi; | ||
500 | int rc = 0; | 501 | int rc = 0; |
501 | 502 | ||
502 | /* Released in ecryptfs_put_super() */ | 503 | /* Released in ecryptfs_put_super() */ |
503 | ecryptfs_set_superblock_private(sb, | 504 | ecryptfs_set_superblock_private(sb, |
504 | kmem_cache_zalloc(ecryptfs_sb_info_cache, | 505 | kmem_cache_zalloc(ecryptfs_sb_info_cache, |
505 | GFP_KERNEL)); | 506 | GFP_KERNEL)); |
506 | if (!ecryptfs_superblock_to_private(sb)) { | 507 | esi = ecryptfs_superblock_to_private(sb); |
508 | if (!esi) { | ||
507 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | 509 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); |
508 | rc = -ENOMEM; | 510 | rc = -ENOMEM; |
509 | goto out; | 511 | goto out; |
510 | } | 512 | } |
513 | |||
514 | rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
515 | if (rc) | ||
516 | goto out; | ||
517 | |||
518 | sb->s_bdi = &esi->bdi; | ||
511 | sb->s_op = &ecryptfs_sops; | 519 | sb->s_op = &ecryptfs_sops; |
512 | /* Released through deactivate_super(sb) from get_sb_nodev */ | 520 | /* Released through deactivate_super(sb) from get_sb_nodev */ |
513 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | 521 | sb->s_root = d_alloc(NULL, &(const struct qstr) { |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 278743c7716a..0c0ae491d231 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb) | |||
122 | lock_kernel(); | 122 | lock_kernel(); |
123 | 123 | ||
124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | 124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); |
125 | bdi_destroy(&sb_info->bdi); | ||
125 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | 126 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); |
126 | ecryptfs_set_superblock_private(sb, NULL); | 127 | ecryptfs_set_superblock_private(sb, NULL); |
127 | 128 | ||
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 8442e353309f..22721b2fd890 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/time.h> | 37 | #include <linux/time.h> |
38 | #include <linux/backing-dev.h> | ||
38 | #include "common.h" | 39 | #include "common.h" |
39 | 40 | ||
40 | /* FIXME: Remove once pnfs hits mainline | 41 | /* FIXME: Remove once pnfs hits mainline |
@@ -84,6 +85,7 @@ struct exofs_sb_info { | |||
84 | u32 s_next_generation; /* next gen # to use */ | 85 | u32 s_next_generation; /* next gen # to use */ |
85 | atomic_t s_curr_pending; /* number of pending commands */ | 86 | atomic_t s_curr_pending; /* number of pending commands */ |
86 | uint8_t s_cred[OSD_CAP_LEN]; /* credential for the fscb */ | 87 | uint8_t s_cred[OSD_CAP_LEN]; /* credential for the fscb */ |
88 | struct backing_dev_info bdi; /* register our bdi with VFS */ | ||
87 | 89 | ||
88 | struct pnfs_osd_data_map data_map; /* Default raid to use | 90 | struct pnfs_osd_data_map data_map; /* Default raid to use |
89 | * FIXME: Needed ? | 91 | * FIXME: Needed ? |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 18e57ea1e5b4..03149b9a5178 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -302,6 +302,7 @@ static void exofs_put_super(struct super_block *sb) | |||
302 | _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], | 302 | _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], |
303 | sbi->layout.s_pid); | 303 | sbi->layout.s_pid); |
304 | 304 | ||
305 | bdi_destroy(&sbi->bdi); | ||
305 | exofs_free_sbi(sbi); | 306 | exofs_free_sbi(sbi); |
306 | sb->s_fs_info = NULL; | 307 | sb->s_fs_info = NULL; |
307 | } | 308 | } |
@@ -546,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
546 | if (!sbi) | 547 | if (!sbi) |
547 | return -ENOMEM; | 548 | return -ENOMEM; |
548 | 549 | ||
550 | ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY); | ||
551 | if (ret) | ||
552 | goto free_bdi; | ||
553 | |||
549 | /* use mount options to fill superblock */ | 554 | /* use mount options to fill superblock */ |
550 | od = osduld_path_lookup(opts->dev_name); | 555 | od = osduld_path_lookup(opts->dev_name); |
551 | if (IS_ERR(od)) { | 556 | if (IS_ERR(od)) { |
@@ -612,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
612 | } | 617 | } |
613 | 618 | ||
614 | /* set up operation vectors */ | 619 | /* set up operation vectors */ |
620 | sb->s_bdi = &sbi->bdi; | ||
615 | sb->s_fs_info = sbi; | 621 | sb->s_fs_info = sbi; |
616 | sb->s_op = &exofs_sops; | 622 | sb->s_op = &exofs_sops; |
617 | sb->s_export_op = &exofs_export_ops; | 623 | sb->s_export_op = &exofs_export_ops; |
@@ -643,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
643 | return 0; | 649 | return 0; |
644 | 650 | ||
645 | free_sbi: | 651 | free_sbi: |
652 | bdi_destroy(&sbi->bdi); | ||
653 | free_bdi: | ||
646 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", | 654 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", |
647 | opts->dev_name, sbi->layout.s_pid, ret); | 655 | opts->dev_name, sbi->layout.s_pid, ret); |
648 | exofs_free_sbi(sbi); | 656 | exofs_free_sbi(sbi); |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 94c8ee81f5e1..236b834b4ca8 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3879,6 +3879,7 @@ static int ext4_xattr_fiemap(struct inode *inode, | |||
3879 | physical += offset; | 3879 | physical += offset; |
3880 | length = EXT4_SB(inode->i_sb)->s_inode_size - offset; | 3880 | length = EXT4_SB(inode->i_sb)->s_inode_size - offset; |
3881 | flags |= FIEMAP_EXTENT_DATA_INLINE; | 3881 | flags |= FIEMAP_EXTENT_DATA_INLINE; |
3882 | brelse(iloc.bh); | ||
3882 | } else { /* external block */ | 3883 | } else { /* external block */ |
3883 | physical = EXT4_I(inode)->i_file_acl << blockbits; | 3884 | physical = EXT4_I(inode)->i_file_acl << blockbits; |
3884 | length = inode->i_sb->s_blocksize; | 3885 | length = inode->i_sb->s_blocksize; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5381802d6052..81d605412844 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5375,7 +5375,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
5375 | } else { | 5375 | } else { |
5376 | struct ext4_iloc iloc; | 5376 | struct ext4_iloc iloc; |
5377 | 5377 | ||
5378 | err = ext4_get_inode_loc(inode, &iloc); | 5378 | err = __ext4_get_inode_loc(inode, &iloc, 0); |
5379 | if (err) | 5379 | if (err) |
5380 | return err; | 5380 | return err; |
5381 | if (wbc->sync_mode == WB_SYNC_ALL) | 5381 | if (wbc->sync_mode == WB_SYNC_ALL) |
@@ -5386,6 +5386,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
5386 | (unsigned long long)iloc.bh->b_blocknr); | 5386 | (unsigned long long)iloc.bh->b_blocknr); |
5387 | err = -EIO; | 5387 | err = -EIO; |
5388 | } | 5388 | } |
5389 | brelse(iloc.bh); | ||
5389 | } | 5390 | } |
5390 | return err; | 5391 | return err; |
5391 | } | 5392 | } |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index bde9d0b170c2..b423a364dca3 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2535,6 +2535,17 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | |||
2535 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", | 2535 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", |
2536 | entry->count, entry->group, entry); | 2536 | entry->count, entry->group, entry); |
2537 | 2537 | ||
2538 | if (test_opt(sb, DISCARD)) { | ||
2539 | ext4_fsblk_t discard_block; | ||
2540 | |||
2541 | discard_block = entry->start_blk + | ||
2542 | ext4_group_first_block_no(sb, entry->group); | ||
2543 | trace_ext4_discard_blocks(sb, | ||
2544 | (unsigned long long)discard_block, | ||
2545 | entry->count); | ||
2546 | sb_issue_discard(sb, discard_block, entry->count); | ||
2547 | } | ||
2548 | |||
2538 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); | 2549 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); |
2539 | /* we expect to find existing buddy because it's pinned */ | 2550 | /* we expect to find existing buddy because it's pinned */ |
2540 | BUG_ON(err != 0); | 2551 | BUG_ON(err != 0); |
@@ -2556,16 +2567,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | |||
2556 | page_cache_release(e4b.bd_bitmap_page); | 2567 | page_cache_release(e4b.bd_bitmap_page); |
2557 | } | 2568 | } |
2558 | ext4_unlock_group(sb, entry->group); | 2569 | ext4_unlock_group(sb, entry->group); |
2559 | if (test_opt(sb, DISCARD)) { | ||
2560 | ext4_fsblk_t discard_block; | ||
2561 | |||
2562 | discard_block = entry->start_blk + | ||
2563 | ext4_group_first_block_no(sb, entry->group); | ||
2564 | trace_ext4_discard_blocks(sb, | ||
2565 | (unsigned long long)discard_block, | ||
2566 | entry->count); | ||
2567 | sb_issue_discard(sb, discard_block, entry->count); | ||
2568 | } | ||
2569 | kmem_cache_free(ext4_free_ext_cachep, entry); | 2570 | kmem_cache_free(ext4_free_ext_cachep, entry); |
2570 | ext4_mb_release_desc(&e4b); | 2571 | ext4_mb_release_desc(&e4b); |
2571 | } | 2572 | } |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 6c751106c2e5..7faefb4da939 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -228,14 +228,23 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
228 | 228 | ||
229 | #ifdef CONFIG_BLOCK | 229 | #ifdef CONFIG_BLOCK |
230 | 230 | ||
231 | #define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) | 231 | static inline sector_t logical_to_blk(struct inode *inode, loff_t offset) |
232 | #define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); | 232 | { |
233 | return (offset >> inode->i_blkbits); | ||
234 | } | ||
235 | |||
236 | static inline loff_t blk_to_logical(struct inode *inode, sector_t blk) | ||
237 | { | ||
238 | return (blk << inode->i_blkbits); | ||
239 | } | ||
233 | 240 | ||
234 | /** | 241 | /** |
235 | * __generic_block_fiemap - FIEMAP for block based inodes (no locking) | 242 | * __generic_block_fiemap - FIEMAP for block based inodes (no locking) |
236 | * @inode - the inode to map | 243 | * @inode: the inode to map |
237 | * @arg - the pointer to userspace where we copy everything to | 244 | * @fieinfo: the fiemap info struct that will be passed back to userspace |
238 | * @get_block - the fs's get_block function | 245 | * @start: where to start mapping in the inode |
246 | * @len: how much space to map | ||
247 | * @get_block: the fs's get_block function | ||
239 | * | 248 | * |
240 | * This does FIEMAP for block based inodes. Basically it will just loop | 249 | * This does FIEMAP for block based inodes. Basically it will just loop |
241 | * through get_block until we hit the number of extents we want to map, or we | 250 | * through get_block until we hit the number of extents we want to map, or we |
@@ -250,58 +259,63 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
250 | */ | 259 | */ |
251 | 260 | ||
252 | int __generic_block_fiemap(struct inode *inode, | 261 | int __generic_block_fiemap(struct inode *inode, |
253 | struct fiemap_extent_info *fieinfo, u64 start, | 262 | struct fiemap_extent_info *fieinfo, loff_t start, |
254 | u64 len, get_block_t *get_block) | 263 | loff_t len, get_block_t *get_block) |
255 | { | 264 | { |
256 | struct buffer_head tmp; | 265 | struct buffer_head map_bh; |
257 | unsigned long long start_blk; | 266 | sector_t start_blk, last_blk; |
258 | long long length = 0, map_len = 0; | 267 | loff_t isize = i_size_read(inode); |
259 | u64 logical = 0, phys = 0, size = 0; | 268 | u64 logical = 0, phys = 0, size = 0; |
260 | u32 flags = FIEMAP_EXTENT_MERGED; | 269 | u32 flags = FIEMAP_EXTENT_MERGED; |
261 | int ret = 0, past_eof = 0, whole_file = 0; | 270 | bool past_eof = false, whole_file = false; |
271 | int ret = 0; | ||
262 | 272 | ||
263 | if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC))) | 273 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); |
274 | if (ret) | ||
264 | return ret; | 275 | return ret; |
265 | 276 | ||
266 | start_blk = logical_to_blk(inode, start); | 277 | /* |
267 | 278 | * Either the i_mutex or other appropriate locking needs to be held | |
268 | length = (long long)min_t(u64, len, i_size_read(inode)); | 279 | * since we expect isize to not change at all through the duration of |
269 | if (length < len) | 280 | * this call. |
270 | whole_file = 1; | 281 | */ |
282 | if (len >= isize) { | ||
283 | whole_file = true; | ||
284 | len = isize; | ||
285 | } | ||
271 | 286 | ||
272 | map_len = length; | 287 | start_blk = logical_to_blk(inode, start); |
288 | last_blk = logical_to_blk(inode, start + len - 1); | ||
273 | 289 | ||
274 | do { | 290 | do { |
275 | /* | 291 | /* |
276 | * we set b_size to the total size we want so it will map as | 292 | * we set b_size to the total size we want so it will map as |
277 | * many contiguous blocks as possible at once | 293 | * many contiguous blocks as possible at once |
278 | */ | 294 | */ |
279 | memset(&tmp, 0, sizeof(struct buffer_head)); | 295 | memset(&map_bh, 0, sizeof(struct buffer_head)); |
280 | tmp.b_size = map_len; | 296 | map_bh.b_size = len; |
281 | 297 | ||
282 | ret = get_block(inode, start_blk, &tmp, 0); | 298 | ret = get_block(inode, start_blk, &map_bh, 0); |
283 | if (ret) | 299 | if (ret) |
284 | break; | 300 | break; |
285 | 301 | ||
286 | /* HOLE */ | 302 | /* HOLE */ |
287 | if (!buffer_mapped(&tmp)) { | 303 | if (!buffer_mapped(&map_bh)) { |
288 | length -= blk_to_logical(inode, 1); | ||
289 | start_blk++; | 304 | start_blk++; |
290 | 305 | ||
291 | /* | 306 | /* |
292 | * we want to handle the case where there is an | 307 | * We want to handle the case where there is an |
293 | * allocated block at the front of the file, and then | 308 | * allocated block at the front of the file, and then |
294 | * nothing but holes up to the end of the file properly, | 309 | * nothing but holes up to the end of the file properly, |
295 | * to make sure that extent at the front gets properly | 310 | * to make sure that extent at the front gets properly |
296 | * marked with FIEMAP_EXTENT_LAST | 311 | * marked with FIEMAP_EXTENT_LAST |
297 | */ | 312 | */ |
298 | if (!past_eof && | 313 | if (!past_eof && |
299 | blk_to_logical(inode, start_blk) >= | 314 | blk_to_logical(inode, start_blk) >= isize) |
300 | blk_to_logical(inode, 0)+i_size_read(inode)) | ||
301 | past_eof = 1; | 315 | past_eof = 1; |
302 | 316 | ||
303 | /* | 317 | /* |
304 | * first hole after going past the EOF, this is our | 318 | * First hole after going past the EOF, this is our |
305 | * last extent | 319 | * last extent |
306 | */ | 320 | */ |
307 | if (past_eof && size) { | 321 | if (past_eof && size) { |
@@ -309,15 +323,18 @@ int __generic_block_fiemap(struct inode *inode, | |||
309 | ret = fiemap_fill_next_extent(fieinfo, logical, | 323 | ret = fiemap_fill_next_extent(fieinfo, logical, |
310 | phys, size, | 324 | phys, size, |
311 | flags); | 325 | flags); |
312 | break; | 326 | } else if (size) { |
327 | ret = fiemap_fill_next_extent(fieinfo, logical, | ||
328 | phys, size, flags); | ||
329 | size = 0; | ||
313 | } | 330 | } |
314 | 331 | ||
315 | /* if we have holes up to/past EOF then we're done */ | 332 | /* if we have holes up to/past EOF then we're done */ |
316 | if (length <= 0 || past_eof) | 333 | if (start_blk > last_blk || past_eof || ret) |
317 | break; | 334 | break; |
318 | } else { | 335 | } else { |
319 | /* | 336 | /* |
320 | * we have gone over the length of what we wanted to | 337 | * We have gone over the length of what we wanted to |
321 | * map, and it wasn't the entire file, so add the extent | 338 | * map, and it wasn't the entire file, so add the extent |
322 | * we got last time and exit. | 339 | * we got last time and exit. |
323 | * | 340 | * |
@@ -331,7 +348,7 @@ int __generic_block_fiemap(struct inode *inode, | |||
331 | * are good to go, just add the extent to the fieinfo | 348 | * are good to go, just add the extent to the fieinfo |
332 | * and break | 349 | * and break |
333 | */ | 350 | */ |
334 | if (length <= 0 && !whole_file) { | 351 | if (start_blk > last_blk && !whole_file) { |
335 | ret = fiemap_fill_next_extent(fieinfo, logical, | 352 | ret = fiemap_fill_next_extent(fieinfo, logical, |
336 | phys, size, | 353 | phys, size, |
337 | flags); | 354 | flags); |
@@ -351,11 +368,10 @@ int __generic_block_fiemap(struct inode *inode, | |||
351 | } | 368 | } |
352 | 369 | ||
353 | logical = blk_to_logical(inode, start_blk); | 370 | logical = blk_to_logical(inode, start_blk); |
354 | phys = blk_to_logical(inode, tmp.b_blocknr); | 371 | phys = blk_to_logical(inode, map_bh.b_blocknr); |
355 | size = tmp.b_size; | 372 | size = map_bh.b_size; |
356 | flags = FIEMAP_EXTENT_MERGED; | 373 | flags = FIEMAP_EXTENT_MERGED; |
357 | 374 | ||
358 | length -= tmp.b_size; | ||
359 | start_blk += logical_to_blk(inode, size); | 375 | start_blk += logical_to_blk(inode, size); |
360 | 376 | ||
361 | /* | 377 | /* |
@@ -363,15 +379,13 @@ int __generic_block_fiemap(struct inode *inode, | |||
363 | * soon as we find a hole that the last extent we found | 379 | * soon as we find a hole that the last extent we found |
364 | * is marked with FIEMAP_EXTENT_LAST | 380 | * is marked with FIEMAP_EXTENT_LAST |
365 | */ | 381 | */ |
366 | if (!past_eof && | 382 | if (!past_eof && logical + size >= isize) |
367 | logical+size >= | 383 | past_eof = true; |
368 | blk_to_logical(inode, 0)+i_size_read(inode)) | ||
369 | past_eof = 1; | ||
370 | } | 384 | } |
371 | cond_resched(); | 385 | cond_resched(); |
372 | } while (1); | 386 | } while (1); |
373 | 387 | ||
374 | /* if ret is 1 then we just hit the end of the extent array */ | 388 | /* If ret is 1 then we just hit the end of the extent array */ |
375 | if (ret == 1) | 389 | if (ret == 1) |
376 | ret = 0; | 390 | ret = 0; |
377 | 391 | ||
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index cf98da1be23e..fa3385154023 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
526 | sb->s_blocksize_bits = 10; | 526 | sb->s_blocksize_bits = 10; |
527 | sb->s_magic = NCP_SUPER_MAGIC; | 527 | sb->s_magic = NCP_SUPER_MAGIC; |
528 | sb->s_op = &ncp_sops; | 528 | sb->s_op = &ncp_sops; |
529 | sb->s_bdi = &server->bdi; | ||
529 | 530 | ||
530 | server = NCP_SBP(sb); | 531 | server = NCP_SBP(sb); |
531 | memset(server, 0, sizeof(*server)); | 532 | memset(server, 0, sizeof(*server)); |
532 | 533 | ||
534 | error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY); | ||
535 | if (error) | ||
536 | goto out_bdi; | ||
537 | |||
533 | server->ncp_filp = ncp_filp; | 538 | server->ncp_filp = ncp_filp; |
534 | server->ncp_sock = sock; | 539 | server->ncp_sock = sock; |
535 | 540 | ||
@@ -719,6 +724,8 @@ out_fput2: | |||
719 | if (server->info_filp) | 724 | if (server->info_filp) |
720 | fput(server->info_filp); | 725 | fput(server->info_filp); |
721 | out_fput: | 726 | out_fput: |
727 | bdi_destroy(&server->bdi); | ||
728 | out_bdi: | ||
722 | /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: | 729 | /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: |
723 | * | 730 | * |
724 | * The previously used put_filp(ncp_filp); was bogous, since | 731 | * The previously used put_filp(ncp_filp); was bogous, since |
@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb) | |||
756 | kill_pid(server->m.wdog_pid, SIGTERM, 1); | 763 | kill_pid(server->m.wdog_pid, SIGTERM, 1); |
757 | put_pid(server->m.wdog_pid); | 764 | put_pid(server->m.wdog_pid); |
758 | 765 | ||
766 | bdi_destroy(&server->bdi); | ||
759 | kfree(server->priv.data); | 767 | kfree(server->priv.data); |
760 | kfree(server->auth.object_name); | 768 | kfree(server->auth.object_name); |
761 | vfree(server->rxbuf); | 769 | vfree(server->rxbuf); |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index a8766c4ef2e0..acc9c4943b84 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -966,6 +966,8 @@ out_error: | |||
966 | static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) | 966 | static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) |
967 | { | 967 | { |
968 | target->flags = source->flags; | 968 | target->flags = source->flags; |
969 | target->rsize = source->rsize; | ||
970 | target->wsize = source->wsize; | ||
969 | target->acregmin = source->acregmin; | 971 | target->acregmin = source->acregmin; |
970 | target->acregmax = source->acregmax; | 972 | target->acregmax = source->acregmax; |
971 | target->acdirmin = source->acdirmin; | 973 | target->acdirmin = source->acdirmin; |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index be46f26c9a56..a7bb5c694aa3 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -837,6 +837,8 @@ out_zap_parent: | |||
837 | /* If we have submounts, don't unhash ! */ | 837 | /* If we have submounts, don't unhash ! */ |
838 | if (have_submounts(dentry)) | 838 | if (have_submounts(dentry)) |
839 | goto out_valid; | 839 | goto out_valid; |
840 | if (dentry->d_flags & DCACHE_DISCONNECTED) | ||
841 | goto out_valid; | ||
840 | shrink_dcache_parent(dentry); | 842 | shrink_dcache_parent(dentry); |
841 | } | 843 | } |
842 | d_drop(dentry); | 844 | d_drop(dentry); |
@@ -1050,7 +1052,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1050 | struct inode *dir; | 1052 | struct inode *dir; |
1051 | int openflags, ret = 0; | 1053 | int openflags, ret = 0; |
1052 | 1054 | ||
1053 | if (!is_atomic_open(nd)) | 1055 | if (!is_atomic_open(nd) || d_mountpoint(dentry)) |
1054 | goto no_open; | 1056 | goto no_open; |
1055 | parent = dget_parent(dentry); | 1057 | parent = dget_parent(dentry); |
1056 | dir = parent->d_inode; | 1058 | dir = parent->d_inode; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 638067007c65..071fcedd517c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -5218,9 +5218,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) | |||
5218 | msg.rpc_resp = &calldata->res; | 5218 | msg.rpc_resp = &calldata->res; |
5219 | task_setup_data.callback_data = calldata; | 5219 | task_setup_data.callback_data = calldata; |
5220 | task = rpc_run_task(&task_setup_data); | 5220 | task = rpc_run_task(&task_setup_data); |
5221 | if (IS_ERR(task)) | 5221 | if (IS_ERR(task)) { |
5222 | status = PTR_ERR(task); | 5222 | status = PTR_ERR(task); |
5223 | goto out; | ||
5224 | } | ||
5223 | rpc_put_task(task); | 5225 | rpc_put_task(task); |
5226 | return 0; | ||
5224 | out: | 5227 | out: |
5225 | dprintk("<-- %s status=%d\n", __func__, status); | 5228 | dprintk("<-- %s status=%d\n", __func__, status); |
5226 | return status; | 5229 | return status; |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e01637240eeb..b4148fc00f9f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2187,6 +2187,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
2187 | if (data->version == 4) { | 2187 | if (data->version == 4) { |
2188 | error = nfs4_try_mount(flags, dev_name, data, mnt); | 2188 | error = nfs4_try_mount(flags, dev_name, data, mnt); |
2189 | kfree(data->client_address); | 2189 | kfree(data->client_address); |
2190 | kfree(data->nfs_server.export_path); | ||
2190 | goto out; | 2191 | goto out; |
2191 | } | 2192 | } |
2192 | #endif /* CONFIG_NFS_V4 */ | 2193 | #endif /* CONFIG_NFS_V4 */ |
@@ -2657,7 +2658,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt) | |||
2657 | devname = nfs_path(path->mnt->mnt_devname, | 2658 | devname = nfs_path(path->mnt->mnt_devname, |
2658 | path->mnt->mnt_root, path->dentry, | 2659 | path->mnt->mnt_root, path->dentry, |
2659 | page, PAGE_SIZE); | 2660 | page, PAGE_SIZE); |
2660 | if (devname == NULL) | 2661 | if (IS_ERR(devname)) |
2661 | goto out_freepage; | 2662 | goto out_freepage; |
2662 | tmp = kstrdup(devname, GFP_KERNEL); | 2663 | tmp = kstrdup(devname, GFP_KERNEL); |
2663 | if (tmp == NULL) | 2664 | if (tmp == NULL) |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index de38d63aa920..3aea3ca98ab7 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1201,6 +1201,25 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data) | |||
1201 | 1201 | ||
1202 | 1202 | ||
1203 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1203 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1204 | static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait) | ||
1205 | { | ||
1206 | if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags)) | ||
1207 | return 1; | ||
1208 | if (may_wait && !out_of_line_wait_on_bit_lock(&nfsi->flags, | ||
1209 | NFS_INO_COMMIT, nfs_wait_bit_killable, | ||
1210 | TASK_KILLABLE)) | ||
1211 | return 1; | ||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | static void nfs_commit_clear_lock(struct nfs_inode *nfsi) | ||
1216 | { | ||
1217 | clear_bit(NFS_INO_COMMIT, &nfsi->flags); | ||
1218 | smp_mb__after_clear_bit(); | ||
1219 | wake_up_bit(&nfsi->flags, NFS_INO_COMMIT); | ||
1220 | } | ||
1221 | |||
1222 | |||
1204 | static void nfs_commitdata_release(void *data) | 1223 | static void nfs_commitdata_release(void *data) |
1205 | { | 1224 | { |
1206 | struct nfs_write_data *wdata = data; | 1225 | struct nfs_write_data *wdata = data; |
@@ -1262,8 +1281,6 @@ static int nfs_commit_rpcsetup(struct list_head *head, | |||
1262 | task = rpc_run_task(&task_setup_data); | 1281 | task = rpc_run_task(&task_setup_data); |
1263 | if (IS_ERR(task)) | 1282 | if (IS_ERR(task)) |
1264 | return PTR_ERR(task); | 1283 | return PTR_ERR(task); |
1265 | if (how & FLUSH_SYNC) | ||
1266 | rpc_wait_for_completion_task(task); | ||
1267 | rpc_put_task(task); | 1284 | rpc_put_task(task); |
1268 | return 0; | 1285 | return 0; |
1269 | } | 1286 | } |
@@ -1294,6 +1311,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) | |||
1294 | BDI_RECLAIMABLE); | 1311 | BDI_RECLAIMABLE); |
1295 | nfs_clear_page_tag_locked(req); | 1312 | nfs_clear_page_tag_locked(req); |
1296 | } | 1313 | } |
1314 | nfs_commit_clear_lock(NFS_I(inode)); | ||
1297 | return -ENOMEM; | 1315 | return -ENOMEM; |
1298 | } | 1316 | } |
1299 | 1317 | ||
@@ -1349,6 +1367,7 @@ static void nfs_commit_release(void *calldata) | |||
1349 | next: | 1367 | next: |
1350 | nfs_clear_page_tag_locked(req); | 1368 | nfs_clear_page_tag_locked(req); |
1351 | } | 1369 | } |
1370 | nfs_commit_clear_lock(NFS_I(data->inode)); | ||
1352 | nfs_commitdata_release(calldata); | 1371 | nfs_commitdata_release(calldata); |
1353 | } | 1372 | } |
1354 | 1373 | ||
@@ -1363,8 +1382,11 @@ static const struct rpc_call_ops nfs_commit_ops = { | |||
1363 | static int nfs_commit_inode(struct inode *inode, int how) | 1382 | static int nfs_commit_inode(struct inode *inode, int how) |
1364 | { | 1383 | { |
1365 | LIST_HEAD(head); | 1384 | LIST_HEAD(head); |
1366 | int res; | 1385 | int may_wait = how & FLUSH_SYNC; |
1386 | int res = 0; | ||
1367 | 1387 | ||
1388 | if (!nfs_commit_set_lock(NFS_I(inode), may_wait)) | ||
1389 | goto out; | ||
1368 | spin_lock(&inode->i_lock); | 1390 | spin_lock(&inode->i_lock); |
1369 | res = nfs_scan_commit(inode, &head, 0, 0); | 1391 | res = nfs_scan_commit(inode, &head, 0, 0); |
1370 | spin_unlock(&inode->i_lock); | 1392 | spin_unlock(&inode->i_lock); |
@@ -1372,7 +1394,13 @@ static int nfs_commit_inode(struct inode *inode, int how) | |||
1372 | int error = nfs_commit_list(inode, &head, how); | 1394 | int error = nfs_commit_list(inode, &head, how); |
1373 | if (error < 0) | 1395 | if (error < 0) |
1374 | return error; | 1396 | return error; |
1375 | } | 1397 | if (may_wait) |
1398 | wait_on_bit(&NFS_I(inode)->flags, NFS_INO_COMMIT, | ||
1399 | nfs_wait_bit_killable, | ||
1400 | TASK_KILLABLE); | ||
1401 | } else | ||
1402 | nfs_commit_clear_lock(NFS_I(inode)); | ||
1403 | out: | ||
1376 | return res; | 1404 | return res; |
1377 | } | 1405 | } |
1378 | 1406 | ||
@@ -1444,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) | |||
1444 | 1472 | ||
1445 | BUG_ON(!PageLocked(page)); | 1473 | BUG_ON(!PageLocked(page)); |
1446 | for (;;) { | 1474 | for (;;) { |
1475 | wait_on_page_writeback(page); | ||
1447 | req = nfs_page_find_request(page); | 1476 | req = nfs_page_find_request(page); |
1448 | if (req == NULL) | 1477 | if (req == NULL) |
1449 | break; | 1478 | break; |
@@ -1478,30 +1507,18 @@ int nfs_wb_page(struct inode *inode, struct page *page) | |||
1478 | .range_start = range_start, | 1507 | .range_start = range_start, |
1479 | .range_end = range_end, | 1508 | .range_end = range_end, |
1480 | }; | 1509 | }; |
1481 | struct nfs_page *req; | ||
1482 | int need_commit; | ||
1483 | int ret; | 1510 | int ret; |
1484 | 1511 | ||
1485 | while(PagePrivate(page)) { | 1512 | while(PagePrivate(page)) { |
1513 | wait_on_page_writeback(page); | ||
1486 | if (clear_page_dirty_for_io(page)) { | 1514 | if (clear_page_dirty_for_io(page)) { |
1487 | ret = nfs_writepage_locked(page, &wbc); | 1515 | ret = nfs_writepage_locked(page, &wbc); |
1488 | if (ret < 0) | 1516 | if (ret < 0) |
1489 | goto out_error; | 1517 | goto out_error; |
1490 | } | 1518 | } |
1491 | req = nfs_find_and_lock_request(page); | 1519 | ret = sync_inode(inode, &wbc); |
1492 | if (!req) | 1520 | if (ret < 0) |
1493 | break; | ||
1494 | if (IS_ERR(req)) { | ||
1495 | ret = PTR_ERR(req); | ||
1496 | goto out_error; | 1521 | goto out_error; |
1497 | } | ||
1498 | need_commit = test_bit(PG_CLEAN, &req->wb_flags); | ||
1499 | nfs_clear_page_tag_locked(req); | ||
1500 | if (need_commit) { | ||
1501 | ret = nfs_commit_inode(inode, FLUSH_SYNC); | ||
1502 | if (ret < 0) | ||
1503 | goto out_error; | ||
1504 | } | ||
1505 | } | 1522 | } |
1506 | return 0; | 1523 | return 0; |
1507 | out_error: | 1524 | out_error: |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index e1703175ee28..34ccf815ea8a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -161,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) | |||
161 | argp->p = page_address(argp->pagelist[0]); | 161 | argp->p = page_address(argp->pagelist[0]); |
162 | argp->pagelist++; | 162 | argp->pagelist++; |
163 | if (argp->pagelen < PAGE_SIZE) { | 163 | if (argp->pagelen < PAGE_SIZE) { |
164 | argp->end = p + (argp->pagelen>>2); | 164 | argp->end = argp->p + (argp->pagelen>>2); |
165 | argp->pagelen = 0; | 165 | argp->pagelen = 0; |
166 | } else { | 166 | } else { |
167 | argp->end = p + (PAGE_SIZE>>2); | 167 | argp->end = argp->p + (PAGE_SIZE>>2); |
168 | argp->pagelen -= PAGE_SIZE; | 168 | argp->pagelen -= PAGE_SIZE; |
169 | } | 169 | } |
170 | memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); | 170 | memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); |
@@ -1426,10 +1426,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1426 | argp->p = page_address(argp->pagelist[0]); | 1426 | argp->p = page_address(argp->pagelist[0]); |
1427 | argp->pagelist++; | 1427 | argp->pagelist++; |
1428 | if (argp->pagelen < PAGE_SIZE) { | 1428 | if (argp->pagelen < PAGE_SIZE) { |
1429 | argp->end = p + (argp->pagelen>>2); | 1429 | argp->end = argp->p + (argp->pagelen>>2); |
1430 | argp->pagelen = 0; | 1430 | argp->pagelen = 0; |
1431 | } else { | 1431 | } else { |
1432 | argp->end = p + (PAGE_SIZE>>2); | 1432 | argp->end = argp->p + (PAGE_SIZE>>2); |
1433 | argp->pagelen -= PAGE_SIZE; | 1433 | argp->pagelen -= PAGE_SIZE; |
1434 | } | 1434 | } |
1435 | } | 1435 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 7621db800a74..8418fcc0a6ab 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2909,7 +2909,7 @@ out_no_task: | |||
2909 | */ | 2909 | */ |
2910 | static const struct pid_entry tid_base_stuff[] = { | 2910 | static const struct pid_entry tid_base_stuff[] = { |
2911 | DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), | 2911 | DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), |
2912 | DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations), | 2912 | DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations), |
2913 | REG("environ", S_IRUSR, proc_environ_operations), | 2913 | REG("environ", S_IRUSR, proc_environ_operations), |
2914 | INF("auxv", S_IRUSR, proc_pid_auxv), | 2914 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2915 | ONE("status", S_IRUGO, proc_pid_status), | 2915 | ONE("status", S_IRUGO, proc_pid_status), |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index f8a6075abf50..07930449a958 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -46,8 +46,6 @@ static inline bool is_privroot_deh(struct dentry *dir, | |||
46 | struct reiserfs_de_head *deh) | 46 | struct reiserfs_de_head *deh) |
47 | { | 47 | { |
48 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; | 48 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; |
49 | if (reiserfs_expose_privroot(dir->d_sb)) | ||
50 | return 0; | ||
51 | return (dir == dir->d_parent && privroot->d_inode && | 49 | return (dir == dir->d_parent && privroot->d_inode && |
52 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); | 50 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); |
53 | } | 51 | } |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 4f9586bb7631..e7cc00e636dc 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -554,7 +554,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
554 | if (!err && new_size < i_size_read(dentry->d_inode)) { | 554 | if (!err && new_size < i_size_read(dentry->d_inode)) { |
555 | struct iattr newattrs = { | 555 | struct iattr newattrs = { |
556 | .ia_ctime = current_fs_time(inode->i_sb), | 556 | .ia_ctime = current_fs_time(inode->i_sb), |
557 | .ia_size = buffer_size, | 557 | .ia_size = new_size, |
558 | .ia_valid = ATTR_SIZE | ATTR_CTIME, | 558 | .ia_valid = ATTR_SIZE | ATTR_CTIME, |
559 | }; | 559 | }; |
560 | 560 | ||
@@ -973,21 +973,13 @@ int reiserfs_permission(struct inode *inode, int mask) | |||
973 | return generic_permission(inode, mask, NULL); | 973 | return generic_permission(inode, mask, NULL); |
974 | } | 974 | } |
975 | 975 | ||
976 | /* This will catch lookups from the fs root to .reiserfs_priv */ | 976 | static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) |
977 | static int | ||
978 | xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) | ||
979 | { | 977 | { |
980 | struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; | 978 | return -EPERM; |
981 | if (container_of(q1, struct dentry, d_name) == priv_root) | ||
982 | return -ENOENT; | ||
983 | if (q1->len == name->len && | ||
984 | !memcmp(q1->name, name->name, name->len)) | ||
985 | return 0; | ||
986 | return 1; | ||
987 | } | 979 | } |
988 | 980 | ||
989 | static const struct dentry_operations xattr_lookup_poison_ops = { | 981 | static const struct dentry_operations xattr_lookup_poison_ops = { |
990 | .d_compare = xattr_lookup_poison, | 982 | .d_revalidate = xattr_hide_revalidate, |
991 | }; | 983 | }; |
992 | 984 | ||
993 | int reiserfs_lookup_privroot(struct super_block *s) | 985 | int reiserfs_lookup_privroot(struct super_block *s) |
@@ -1001,8 +993,7 @@ int reiserfs_lookup_privroot(struct super_block *s) | |||
1001 | strlen(PRIVROOT_NAME)); | 993 | strlen(PRIVROOT_NAME)); |
1002 | if (!IS_ERR(dentry)) { | 994 | if (!IS_ERR(dentry)) { |
1003 | REISERFS_SB(s)->priv_root = dentry; | 995 | REISERFS_SB(s)->priv_root = dentry; |
1004 | if (!reiserfs_expose_privroot(s)) | 996 | dentry->d_op = &xattr_lookup_poison_ops; |
1005 | s->s_root->d_op = &xattr_lookup_poison_ops; | ||
1006 | if (dentry->d_inode) | 997 | if (dentry->d_inode) |
1007 | dentry->d_inode->i_flags |= S_PRIVATE; | 998 | dentry->d_inode->i_flags |= S_PRIVATE; |
1008 | } else | 999 | } else |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 1c4c8f089970..dfa1d67f8fca 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb) | |||
479 | if (server->conn_pid) | 479 | if (server->conn_pid) |
480 | kill_pid(server->conn_pid, SIGTERM, 1); | 480 | kill_pid(server->conn_pid, SIGTERM, 1); |
481 | 481 | ||
482 | bdi_destroy(&server->bdi); | ||
482 | kfree(server->ops); | 483 | kfree(server->ops); |
483 | smb_unload_nls(server); | 484 | smb_unload_nls(server); |
484 | sb->s_fs_info = NULL; | 485 | sb->s_fs_info = NULL; |
@@ -525,6 +526,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
525 | if (!server) | 526 | if (!server) |
526 | goto out_no_server; | 527 | goto out_no_server; |
527 | sb->s_fs_info = server; | 528 | sb->s_fs_info = server; |
529 | |||
530 | if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY)) | ||
531 | goto out_bdi; | ||
532 | |||
533 | sb->s_bdi = &server->bdi; | ||
528 | 534 | ||
529 | server->super_block = sb; | 535 | server->super_block = sb; |
530 | server->mnt = NULL; | 536 | server->mnt = NULL; |
@@ -624,6 +630,8 @@ out_no_smbiod: | |||
624 | out_bad_option: | 630 | out_bad_option: |
625 | kfree(mem); | 631 | kfree(mem); |
626 | out_no_mem: | 632 | out_no_mem: |
633 | bdi_destroy(&server->bdi); | ||
634 | out_bdi: | ||
627 | if (!server->mnt) | 635 | if (!server->mnt) |
628 | printk(KERN_ERR "smb_fill_super: allocation failure\n"); | 636 | printk(KERN_ERR "smb_fill_super: allocation failure\n"); |
629 | sb->s_fs_info = NULL; | 637 | sb->s_fs_info = NULL; |
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 1cb0d81b164b..653c030eb840 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c | |||
@@ -87,9 +87,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
87 | u64 cur_index = index >> msblk->devblksize_log2; | 87 | u64 cur_index = index >> msblk->devblksize_log2; |
88 | int bytes, compressed, b = 0, k = 0, page = 0, avail; | 88 | int bytes, compressed, b = 0, k = 0, page = 0, avail; |
89 | 89 | ||
90 | 90 | bh = kcalloc(((srclength + msblk->devblksize - 1) | |
91 | bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1, | 91 | >> msblk->devblksize_log2) + 1, sizeof(*bh), GFP_KERNEL); |
92 | sizeof(*bh), GFP_KERNEL); | ||
93 | if (bh == NULL) | 92 | if (bh == NULL) |
94 | return -ENOMEM; | 93 | return -ENOMEM; |
95 | 94 | ||
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 3550aec2f655..48b6f4a385a6 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -275,7 +275,8 @@ allocate_root: | |||
275 | 275 | ||
276 | err = squashfs_read_inode(root, root_inode); | 276 | err = squashfs_read_inode(root, root_inode); |
277 | if (err) { | 277 | if (err) { |
278 | iget_failed(root); | 278 | make_bad_inode(root); |
279 | iput(root); | ||
279 | goto failed_mount; | 280 | goto failed_mount; |
280 | } | 281 | } |
281 | insert_inode_hash(root); | 282 | insert_inode_hash(root); |
@@ -353,6 +354,7 @@ static void squashfs_put_super(struct super_block *sb) | |||
353 | kfree(sbi->id_table); | 354 | kfree(sbi->id_table); |
354 | kfree(sbi->fragment_index); | 355 | kfree(sbi->fragment_index); |
355 | kfree(sbi->meta_index); | 356 | kfree(sbi->meta_index); |
357 | kfree(sbi->inode_lookup_table); | ||
356 | kfree(sb->s_fs_info); | 358 | kfree(sb->s_fs_info); |
357 | sb->s_fs_info = NULL; | 359 | sb->s_fs_info = NULL; |
358 | } | 360 | } |
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index 15a03d0fb9f3..7a603874e483 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c | |||
@@ -128,8 +128,9 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, | |||
128 | goto release_mutex; | 128 | goto release_mutex; |
129 | } | 129 | } |
130 | 130 | ||
131 | length = stream->total_out; | ||
131 | mutex_unlock(&msblk->read_data_mutex); | 132 | mutex_unlock(&msblk->read_data_mutex); |
132 | return stream->total_out; | 133 | return length; |
133 | 134 | ||
134 | release_mutex: | 135 | release_mutex: |
135 | mutex_unlock(&msblk->read_data_mutex); | 136 | mutex_unlock(&msblk->read_data_mutex); |
diff --git a/fs/super.c b/fs/super.c index f35ac6022109..1527e6a0ee35 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/kobject.h> | 37 | #include <linux/kobject.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/file.h> | 39 | #include <linux/file.h> |
40 | #include <linux/backing-dev.h> | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include "internal.h" | 42 | #include "internal.h" |
42 | 43 | ||
@@ -693,6 +694,7 @@ int set_anon_super(struct super_block *s, void *data) | |||
693 | return -EMFILE; | 694 | return -EMFILE; |
694 | } | 695 | } |
695 | s->s_dev = MKDEV(0, dev & MINORMASK); | 696 | s->s_dev = MKDEV(0, dev & MINORMASK); |
697 | s->s_bdi = &noop_backing_dev_info; | ||
696 | return 0; | 698 | return 0; |
697 | } | 699 | } |
698 | 700 | ||
@@ -954,10 +956,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
954 | if (error < 0) | 956 | if (error < 0) |
955 | goto out_free_secdata; | 957 | goto out_free_secdata; |
956 | BUG_ON(!mnt->mnt_sb); | 958 | BUG_ON(!mnt->mnt_sb); |
959 | WARN_ON(!mnt->mnt_sb->s_bdi); | ||
957 | 960 | ||
958 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); | 961 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); |
959 | if (error) | 962 | if (error) |
960 | goto out_sb; | 963 | goto out_sb; |
961 | 964 | ||
962 | /* | 965 | /* |
963 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE | 966 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
15 | #include <linux/quotaops.h> | 15 | #include <linux/quotaops.h> |
16 | #include <linux/buffer_head.h> | 16 | #include <linux/buffer_head.h> |
17 | #include <linux/backing-dev.h> | ||
17 | #include "internal.h" | 18 | #include "internal.h" |
18 | 19 | ||
19 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ | 20 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ |
@@ -32,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) | |||
32 | * This should be safe, as we require bdi backing to actually | 33 | * This should be safe, as we require bdi backing to actually |
33 | * write out data in the first place | 34 | * write out data in the first place |
34 | */ | 35 | */ |
35 | if (!sb->s_bdi) | 36 | if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) |
36 | return 0; | 37 | return 0; |
37 | 38 | ||
38 | if (sb->s_qcop && sb->s_qcop->quota_sync) | 39 | if (sb->s_qcop && sb->s_qcop->quota_sync) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 52e06b487ced..29f1edca76de 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1209,6 +1209,7 @@ xfs_fs_put_super( | |||
1209 | 1209 | ||
1210 | xfs_unmountfs(mp); | 1210 | xfs_unmountfs(mp); |
1211 | xfs_freesb(mp); | 1211 | xfs_freesb(mp); |
1212 | xfs_inode_shrinker_unregister(mp); | ||
1212 | xfs_icsb_destroy_counters(mp); | 1213 | xfs_icsb_destroy_counters(mp); |
1213 | xfs_close_devices(mp); | 1214 | xfs_close_devices(mp); |
1214 | xfs_dmops_put(mp); | 1215 | xfs_dmops_put(mp); |
@@ -1622,6 +1623,8 @@ xfs_fs_fill_super( | |||
1622 | if (error) | 1623 | if (error) |
1623 | goto fail_vnrele; | 1624 | goto fail_vnrele; |
1624 | 1625 | ||
1626 | xfs_inode_shrinker_register(mp); | ||
1627 | |||
1625 | kfree(mtpt); | 1628 | kfree(mtpt); |
1626 | return 0; | 1629 | return 0; |
1627 | 1630 | ||
@@ -1867,6 +1870,7 @@ init_xfs_fs(void) | |||
1867 | goto out_cleanup_procfs; | 1870 | goto out_cleanup_procfs; |
1868 | 1871 | ||
1869 | vfs_initquota(); | 1872 | vfs_initquota(); |
1873 | xfs_inode_shrinker_init(); | ||
1870 | 1874 | ||
1871 | error = register_filesystem(&xfs_fs_type); | 1875 | error = register_filesystem(&xfs_fs_type); |
1872 | if (error) | 1876 | if (error) |
@@ -1894,6 +1898,7 @@ exit_xfs_fs(void) | |||
1894 | { | 1898 | { |
1895 | vfs_exitquota(); | 1899 | vfs_exitquota(); |
1896 | unregister_filesystem(&xfs_fs_type); | 1900 | unregister_filesystem(&xfs_fs_type); |
1901 | xfs_inode_shrinker_destroy(); | ||
1897 | xfs_sysctl_unregister(); | 1902 | xfs_sysctl_unregister(); |
1898 | xfs_cleanup_procfs(); | 1903 | xfs_cleanup_procfs(); |
1899 | xfs_buf_terminate(); | 1904 | xfs_buf_terminate(); |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index fd9698215759..a427c638d909 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -95,7 +95,8 @@ xfs_inode_ag_walk( | |||
95 | struct xfs_perag *pag, int flags), | 95 | struct xfs_perag *pag, int flags), |
96 | int flags, | 96 | int flags, |
97 | int tag, | 97 | int tag, |
98 | int exclusive) | 98 | int exclusive, |
99 | int *nr_to_scan) | ||
99 | { | 100 | { |
100 | uint32_t first_index; | 101 | uint32_t first_index; |
101 | int last_error = 0; | 102 | int last_error = 0; |
@@ -134,7 +135,7 @@ restart: | |||
134 | if (error == EFSCORRUPTED) | 135 | if (error == EFSCORRUPTED) |
135 | break; | 136 | break; |
136 | 137 | ||
137 | } while (1); | 138 | } while ((*nr_to_scan)--); |
138 | 139 | ||
139 | if (skipped) { | 140 | if (skipped) { |
140 | delay(1); | 141 | delay(1); |
@@ -150,12 +151,15 @@ xfs_inode_ag_iterator( | |||
150 | struct xfs_perag *pag, int flags), | 151 | struct xfs_perag *pag, int flags), |
151 | int flags, | 152 | int flags, |
152 | int tag, | 153 | int tag, |
153 | int exclusive) | 154 | int exclusive, |
155 | int *nr_to_scan) | ||
154 | { | 156 | { |
155 | int error = 0; | 157 | int error = 0; |
156 | int last_error = 0; | 158 | int last_error = 0; |
157 | xfs_agnumber_t ag; | 159 | xfs_agnumber_t ag; |
160 | int nr; | ||
158 | 161 | ||
162 | nr = nr_to_scan ? *nr_to_scan : INT_MAX; | ||
159 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { | 163 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { |
160 | struct xfs_perag *pag; | 164 | struct xfs_perag *pag; |
161 | 165 | ||
@@ -165,14 +169,18 @@ xfs_inode_ag_iterator( | |||
165 | continue; | 169 | continue; |
166 | } | 170 | } |
167 | error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, | 171 | error = xfs_inode_ag_walk(mp, pag, execute, flags, tag, |
168 | exclusive); | 172 | exclusive, &nr); |
169 | xfs_perag_put(pag); | 173 | xfs_perag_put(pag); |
170 | if (error) { | 174 | if (error) { |
171 | last_error = error; | 175 | last_error = error; |
172 | if (error == EFSCORRUPTED) | 176 | if (error == EFSCORRUPTED) |
173 | break; | 177 | break; |
174 | } | 178 | } |
179 | if (nr <= 0) | ||
180 | break; | ||
175 | } | 181 | } |
182 | if (nr_to_scan) | ||
183 | *nr_to_scan = nr; | ||
176 | return XFS_ERROR(last_error); | 184 | return XFS_ERROR(last_error); |
177 | } | 185 | } |
178 | 186 | ||
@@ -291,7 +299,7 @@ xfs_sync_data( | |||
291 | ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0); | 299 | ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0); |
292 | 300 | ||
293 | error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, | 301 | error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, |
294 | XFS_ICI_NO_TAG, 0); | 302 | XFS_ICI_NO_TAG, 0, NULL); |
295 | if (error) | 303 | if (error) |
296 | return XFS_ERROR(error); | 304 | return XFS_ERROR(error); |
297 | 305 | ||
@@ -310,7 +318,7 @@ xfs_sync_attr( | |||
310 | ASSERT((flags & ~SYNC_WAIT) == 0); | 318 | ASSERT((flags & ~SYNC_WAIT) == 0); |
311 | 319 | ||
312 | return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, | 320 | return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, |
313 | XFS_ICI_NO_TAG, 0); | 321 | XFS_ICI_NO_TAG, 0, NULL); |
314 | } | 322 | } |
315 | 323 | ||
316 | STATIC int | 324 | STATIC int |
@@ -673,6 +681,7 @@ __xfs_inode_set_reclaim_tag( | |||
673 | radix_tree_tag_set(&pag->pag_ici_root, | 681 | radix_tree_tag_set(&pag->pag_ici_root, |
674 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), | 682 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), |
675 | XFS_ICI_RECLAIM_TAG); | 683 | XFS_ICI_RECLAIM_TAG); |
684 | pag->pag_ici_reclaimable++; | ||
676 | } | 685 | } |
677 | 686 | ||
678 | /* | 687 | /* |
@@ -705,6 +714,7 @@ __xfs_inode_clear_reclaim_tag( | |||
705 | { | 714 | { |
706 | radix_tree_tag_clear(&pag->pag_ici_root, | 715 | radix_tree_tag_clear(&pag->pag_ici_root, |
707 | XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); | 716 | XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); |
717 | pag->pag_ici_reclaimable--; | ||
708 | } | 718 | } |
709 | 719 | ||
710 | /* | 720 | /* |
@@ -854,5 +864,93 @@ xfs_reclaim_inodes( | |||
854 | int mode) | 864 | int mode) |
855 | { | 865 | { |
856 | return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode, | 866 | return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode, |
857 | XFS_ICI_RECLAIM_TAG, 1); | 867 | XFS_ICI_RECLAIM_TAG, 1, NULL); |
868 | } | ||
869 | |||
870 | /* | ||
871 | * Shrinker infrastructure. | ||
872 | * | ||
873 | * This is all far more complex than it needs to be. It adds a global list of | ||
874 | * mounts because the shrinkers can only call a global context. We need to make | ||
875 | * the shrinkers pass a context to avoid the need for global state. | ||
876 | */ | ||
877 | static LIST_HEAD(xfs_mount_list); | ||
878 | static struct rw_semaphore xfs_mount_list_lock; | ||
879 | |||
880 | static int | ||
881 | xfs_reclaim_inode_shrink( | ||
882 | int nr_to_scan, | ||
883 | gfp_t gfp_mask) | ||
884 | { | ||
885 | struct xfs_mount *mp; | ||
886 | struct xfs_perag *pag; | ||
887 | xfs_agnumber_t ag; | ||
888 | int reclaimable = 0; | ||
889 | |||
890 | if (nr_to_scan) { | ||
891 | if (!(gfp_mask & __GFP_FS)) | ||
892 | return -1; | ||
893 | |||
894 | down_read(&xfs_mount_list_lock); | ||
895 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { | ||
896 | xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0, | ||
897 | XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan); | ||
898 | if (nr_to_scan <= 0) | ||
899 | break; | ||
900 | } | ||
901 | up_read(&xfs_mount_list_lock); | ||
902 | } | ||
903 | |||
904 | down_read(&xfs_mount_list_lock); | ||
905 | list_for_each_entry(mp, &xfs_mount_list, m_mplist) { | ||
906 | for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) { | ||
907 | |||
908 | pag = xfs_perag_get(mp, ag); | ||
909 | if (!pag->pag_ici_init) { | ||
910 | xfs_perag_put(pag); | ||
911 | continue; | ||
912 | } | ||
913 | reclaimable += pag->pag_ici_reclaimable; | ||
914 | xfs_perag_put(pag); | ||
915 | } | ||
916 | } | ||
917 | up_read(&xfs_mount_list_lock); | ||
918 | return reclaimable; | ||
919 | } | ||
920 | |||
921 | static struct shrinker xfs_inode_shrinker = { | ||
922 | .shrink = xfs_reclaim_inode_shrink, | ||
923 | .seeks = DEFAULT_SEEKS, | ||
924 | }; | ||
925 | |||
926 | void __init | ||
927 | xfs_inode_shrinker_init(void) | ||
928 | { | ||
929 | init_rwsem(&xfs_mount_list_lock); | ||
930 | register_shrinker(&xfs_inode_shrinker); | ||
931 | } | ||
932 | |||
933 | void | ||
934 | xfs_inode_shrinker_destroy(void) | ||
935 | { | ||
936 | ASSERT(list_empty(&xfs_mount_list)); | ||
937 | unregister_shrinker(&xfs_inode_shrinker); | ||
938 | } | ||
939 | |||
940 | void | ||
941 | xfs_inode_shrinker_register( | ||
942 | struct xfs_mount *mp) | ||
943 | { | ||
944 | down_write(&xfs_mount_list_lock); | ||
945 | list_add_tail(&mp->m_mplist, &xfs_mount_list); | ||
946 | up_write(&xfs_mount_list_lock); | ||
947 | } | ||
948 | |||
949 | void | ||
950 | xfs_inode_shrinker_unregister( | ||
951 | struct xfs_mount *mp) | ||
952 | { | ||
953 | down_write(&xfs_mount_list_lock); | ||
954 | list_del(&mp->m_mplist); | ||
955 | up_write(&xfs_mount_list_lock); | ||
858 | } | 956 | } |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index d480c346cabb..cdcbaaca9880 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -53,6 +53,11 @@ void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, | |||
53 | int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag); | 53 | int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag); |
54 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 54 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
55 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), | 55 | int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), |
56 | int flags, int tag, int write_lock); | 56 | int flags, int tag, int write_lock, int *nr_to_scan); |
57 | |||
58 | void xfs_inode_shrinker_init(void); | ||
59 | void xfs_inode_shrinker_destroy(void); | ||
60 | void xfs_inode_shrinker_register(struct xfs_mount *mp); | ||
61 | void xfs_inode_shrinker_unregister(struct xfs_mount *mp); | ||
57 | 62 | ||
58 | #endif | 63 | #endif |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 5d0ee8d492db..50bee07d6b0e 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -891,7 +891,8 @@ xfs_qm_dqrele_all_inodes( | |||
891 | uint flags) | 891 | uint flags) |
892 | { | 892 | { |
893 | ASSERT(mp->m_quotainfo); | 893 | ASSERT(mp->m_quotainfo); |
894 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0); | 894 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, |
895 | XFS_ICI_NO_TAG, 0, NULL); | ||
895 | } | 896 | } |
896 | 897 | ||
897 | /*------------------------------------------------------------------------*/ | 898 | /*------------------------------------------------------------------------*/ |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index b1a5a1ff88ea..abb8222b88c9 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -223,6 +223,7 @@ typedef struct xfs_perag { | |||
223 | int pag_ici_init; /* incore inode cache initialised */ | 223 | int pag_ici_init; /* incore inode cache initialised */ |
224 | rwlock_t pag_ici_lock; /* incore inode lock */ | 224 | rwlock_t pag_ici_lock; /* incore inode lock */ |
225 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ | 225 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ |
226 | int pag_ici_reclaimable; /* reclaimable inodes */ | ||
226 | #endif | 227 | #endif |
227 | int pagb_count; /* pagb slots in use */ | 228 | int pagb_count; /* pagb slots in use */ |
228 | xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */ | 229 | xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index cd27c9d6c71f..5bba29a07812 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -177,16 +177,26 @@ xfs_swap_extents_check_format( | |||
177 | XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max) | 177 | XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max) |
178 | return EINVAL; | 178 | return EINVAL; |
179 | 179 | ||
180 | /* Check root block of temp in btree form to max in target */ | 180 | /* |
181 | * If we are in a btree format, check that the temp root block will fit | ||
182 | * in the target and that it has enough extents to be in btree format | ||
183 | * in the target. | ||
184 | * | ||
185 | * Note that we have to be careful to allow btree->extent conversions | ||
186 | * (a common defrag case) which will occur when the temp inode is in | ||
187 | * extent format... | ||
188 | */ | ||
181 | if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE && | 189 | if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE && |
182 | XFS_IFORK_BOFF(ip) && | 190 | ((XFS_IFORK_BOFF(ip) && |
183 | tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) | 191 | tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) || |
192 | XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= ip->i_df.if_ext_max)) | ||
184 | return EINVAL; | 193 | return EINVAL; |
185 | 194 | ||
186 | /* Check root block of target in btree form to max in temp */ | 195 | /* Reciprocal target->temp btree format checks */ |
187 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && | 196 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && |
188 | XFS_IFORK_BOFF(tip) && | 197 | ((XFS_IFORK_BOFF(tip) && |
189 | ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) | 198 | ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) || |
199 | XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= tip->i_df.if_ext_max)) | ||
190 | return EINVAL; | 200 | return EINVAL; |
191 | 201 | ||
192 | return 0; | 202 | return 0; |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 4fa0bc7b983e..9ff48a16a7ee 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -259,6 +259,7 @@ typedef struct xfs_mount { | |||
259 | wait_queue_head_t m_wait_single_sync_task; | 259 | wait_queue_head_t m_wait_single_sync_task; |
260 | __int64_t m_update_flags; /* sb flags we need to update | 260 | __int64_t m_update_flags; /* sb flags we need to update |
261 | on the next remount,rw */ | 261 | on the next remount,rw */ |
262 | struct list_head m_mplist; /* inode shrinker mount list */ | ||
262 | } xfs_mount_t; | 263 | } xfs_mount_t; |
263 | 264 | ||
264 | /* | 265 | /* |