diff options
Diffstat (limited to 'fs')
105 files changed, 849 insertions, 1170 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index f2434fc9d2c4..6d4d86187c55 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -253,9 +253,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
253 | return ERR_PTR(-ENOMEM); | 253 | return ERR_PTR(-ENOMEM); |
254 | } | 254 | } |
255 | 255 | ||
256 | inode->i_mode = mode; | 256 | inode_init_owner(inode, NULL, mode); |
257 | inode->i_uid = current_fsuid(); | ||
258 | inode->i_gid = current_fsgid(); | ||
259 | inode->i_blocks = 0; | 257 | inode->i_blocks = 0; |
260 | inode->i_rdev = 0; | 258 | inode->i_rdev = 0; |
261 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 259 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/Makefile b/fs/Makefile index 97f340f14ba2..e6ec1d309b1d 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.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 fs_struct.o | 14 | stack.o fs_struct.o statfs.o |
15 | 15 | ||
16 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
17 | 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/afs/dir.c b/fs/afs/dir.c index adc1cb771b57..b42d5cc1d6d2 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -189,13 +189,9 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index, | |||
189 | struct key *key) | 189 | struct key *key) |
190 | { | 190 | { |
191 | struct page *page; | 191 | struct page *page; |
192 | struct file file = { | ||
193 | .private_data = key, | ||
194 | }; | ||
195 | |||
196 | _enter("{%lu},%lu", dir->i_ino, index); | 192 | _enter("{%lu},%lu", dir->i_ino, index); |
197 | 193 | ||
198 | page = read_mapping_page(dir->i_mapping, index, &file); | 194 | page = read_cache_page(dir->i_mapping, index, afs_page_filler, key); |
199 | if (!IS_ERR(page)) { | 195 | if (!IS_ERR(page)) { |
200 | kmap(page); | 196 | kmap(page); |
201 | if (!PageChecked(page)) | 197 | if (!PageChecked(page)) |
diff --git a/fs/afs/file.c b/fs/afs/file.c index 0df9bc2b724d..14d89fa58fee 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -121,34 +121,19 @@ static void afs_file_readpage_read_complete(struct page *page, | |||
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | /* | 123 | /* |
124 | * AFS read page from file, directory or symlink | 124 | * read page from file, directory or symlink, given a key to use |
125 | */ | 125 | */ |
126 | static int afs_readpage(struct file *file, struct page *page) | 126 | int afs_page_filler(void *data, struct page *page) |
127 | { | 127 | { |
128 | struct afs_vnode *vnode; | 128 | struct inode *inode = page->mapping->host; |
129 | struct inode *inode; | 129 | struct afs_vnode *vnode = AFS_FS_I(inode); |
130 | struct key *key; | 130 | struct key *key = data; |
131 | size_t len; | 131 | size_t len; |
132 | off_t offset; | 132 | off_t offset; |
133 | int ret; | 133 | int ret; |
134 | 134 | ||
135 | inode = page->mapping->host; | ||
136 | |||
137 | if (file) { | ||
138 | key = file->private_data; | ||
139 | ASSERT(key != NULL); | ||
140 | } else { | ||
141 | key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); | ||
142 | if (IS_ERR(key)) { | ||
143 | ret = PTR_ERR(key); | ||
144 | goto error_nokey; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); | 135 | _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index); |
149 | 136 | ||
150 | vnode = AFS_FS_I(inode); | ||
151 | |||
152 | BUG_ON(!PageLocked(page)); | 137 | BUG_ON(!PageLocked(page)); |
153 | 138 | ||
154 | ret = -ESTALE; | 139 | ret = -ESTALE; |
@@ -214,31 +199,56 @@ static int afs_readpage(struct file *file, struct page *page) | |||
214 | unlock_page(page); | 199 | unlock_page(page); |
215 | } | 200 | } |
216 | 201 | ||
217 | if (!file) | ||
218 | key_put(key); | ||
219 | _leave(" = 0"); | 202 | _leave(" = 0"); |
220 | return 0; | 203 | return 0; |
221 | 204 | ||
222 | error: | 205 | error: |
223 | SetPageError(page); | 206 | SetPageError(page); |
224 | unlock_page(page); | 207 | unlock_page(page); |
225 | if (!file) | ||
226 | key_put(key); | ||
227 | error_nokey: | ||
228 | _leave(" = %d", ret); | 208 | _leave(" = %d", ret); |
229 | return ret; | 209 | return ret; |
230 | } | 210 | } |
231 | 211 | ||
232 | /* | 212 | /* |
213 | * read page from file, directory or symlink, given a file to nominate the key | ||
214 | * to be used | ||
215 | */ | ||
216 | static int afs_readpage(struct file *file, struct page *page) | ||
217 | { | ||
218 | struct key *key; | ||
219 | int ret; | ||
220 | |||
221 | if (file) { | ||
222 | key = file->private_data; | ||
223 | ASSERT(key != NULL); | ||
224 | ret = afs_page_filler(key, page); | ||
225 | } else { | ||
226 | struct inode *inode = page->mapping->host; | ||
227 | key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell); | ||
228 | if (IS_ERR(key)) { | ||
229 | ret = PTR_ERR(key); | ||
230 | } else { | ||
231 | ret = afs_page_filler(key, page); | ||
232 | key_put(key); | ||
233 | } | ||
234 | } | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | /* | ||
233 | * read a set of pages | 239 | * read a set of pages |
234 | */ | 240 | */ |
235 | static int afs_readpages(struct file *file, struct address_space *mapping, | 241 | static int afs_readpages(struct file *file, struct address_space *mapping, |
236 | struct list_head *pages, unsigned nr_pages) | 242 | struct list_head *pages, unsigned nr_pages) |
237 | { | 243 | { |
244 | struct key *key = file->private_data; | ||
238 | struct afs_vnode *vnode; | 245 | struct afs_vnode *vnode; |
239 | int ret = 0; | 246 | int ret = 0; |
240 | 247 | ||
241 | _enter(",{%lu},,%d", mapping->host->i_ino, nr_pages); | 248 | _enter("{%d},{%lu},,%d", |
249 | key_serial(key), mapping->host->i_ino, nr_pages); | ||
250 | |||
251 | ASSERT(key != NULL); | ||
242 | 252 | ||
243 | vnode = AFS_FS_I(mapping->host); | 253 | vnode = AFS_FS_I(mapping->host); |
244 | if (vnode->flags & AFS_VNODE_DELETED) { | 254 | if (vnode->flags & AFS_VNODE_DELETED) { |
@@ -279,7 +289,7 @@ static int afs_readpages(struct file *file, struct address_space *mapping, | |||
279 | } | 289 | } |
280 | 290 | ||
281 | /* load the missing pages from the network */ | 291 | /* load the missing pages from the network */ |
282 | ret = read_cache_pages(mapping, pages, (void *) afs_readpage, file); | 292 | ret = read_cache_pages(mapping, pages, afs_page_filler, key); |
283 | 293 | ||
284 | _leave(" = %d [netting]", ret); | 294 | _leave(" = %d [netting]", ret); |
285 | return ret; | 295 | return ret; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index a10f2582844f..807f284cc75e 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -494,6 +494,7 @@ extern const struct file_operations afs_file_operations; | |||
494 | 494 | ||
495 | extern int afs_open(struct inode *, struct file *); | 495 | extern int afs_open(struct inode *, struct file *); |
496 | extern int afs_release(struct inode *, struct file *); | 496 | extern int afs_release(struct inode *, struct file *); |
497 | extern int afs_page_filler(void *, struct page *); | ||
497 | 498 | ||
498 | /* | 499 | /* |
499 | * flock.c | 500 | * flock.c |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index b3feddc4f7d6..a9e23039ea34 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -49,9 +49,6 @@ static unsigned long afs_mntpt_expiry_timeout = 10 * 60; | |||
49 | */ | 49 | */ |
50 | int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | 50 | int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) |
51 | { | 51 | { |
52 | struct file file = { | ||
53 | .private_data = key, | ||
54 | }; | ||
55 | struct page *page; | 52 | struct page *page; |
56 | size_t size; | 53 | size_t size; |
57 | char *buf; | 54 | char *buf; |
@@ -61,7 +58,8 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | |||
61 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); | 58 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); |
62 | 59 | ||
63 | /* read the contents of the symlink into the pagecache */ | 60 | /* read the contents of the symlink into the pagecache */ |
64 | page = read_mapping_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, &file); | 61 | page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, |
62 | afs_page_filler, key); | ||
65 | if (IS_ERR(page)) { | 63 | if (IS_ERR(page)) { |
66 | ret = PTR_ERR(page); | 64 | ret = PTR_ERR(page); |
67 | goto out; | 65 | goto out; |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index e4b75d6eda83..9bd4b3876c99 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -205,7 +205,7 @@ static struct inode *anon_inode_mkinode(void) | |||
205 | * that it already _is_ on the dirty list. | 205 | * that it already _is_ on the dirty list. |
206 | */ | 206 | */ |
207 | inode->i_state = I_DIRTY; | 207 | inode->i_state = I_DIRTY; |
208 | inode->i_mode = S_IRUSR | S_IWUSR; | 208 | inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR; |
209 | inode->i_uid = current_fsuid(); | 209 | inode->i_uid = current_fsuid(); |
210 | inode->i_gid = current_fsgid(); | 210 | inode->i_gid = current_fsgid(); |
211 | inode->i_flags |= S_PRIVATE; | 211 | inode->i_flags |= S_PRIVATE; |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 1e41aadb1068..8f73841fc974 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -105,14 +105,12 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
105 | } | 105 | } |
106 | set_bit(ino, info->si_imap); | 106 | set_bit(ino, info->si_imap); |
107 | info->si_freei--; | 107 | info->si_freei--; |
108 | inode->i_uid = current_fsuid(); | 108 | inode_init_owner(inode, dir, mode); |
109 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); | ||
110 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 109 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
111 | inode->i_blocks = 0; | 110 | inode->i_blocks = 0; |
112 | inode->i_op = &bfs_file_inops; | 111 | inode->i_op = &bfs_file_inops; |
113 | inode->i_fop = &bfs_file_operations; | 112 | inode->i_fop = &bfs_file_operations; |
114 | inode->i_mapping->a_ops = &bfs_aops; | 113 | inode->i_mapping->a_ops = &bfs_aops; |
115 | inode->i_mode = mode; | ||
116 | inode->i_ino = ino; | 114 | inode->i_ino = ino; |
117 | BFS_I(inode)->i_dsk_ino = ino; | 115 | BFS_I(inode)->i_dsk_ino = ino; |
118 | BFS_I(inode)->i_sblock = 0; | 116 | BFS_I(inode)->i_sblock = 0; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 55dcb7884f4d..26e5f5026620 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -245,37 +245,14 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
245 | sb = get_active_super(bdev); | 245 | sb = get_active_super(bdev); |
246 | if (!sb) | 246 | if (!sb) |
247 | goto out; | 247 | goto out; |
248 | if (sb->s_flags & MS_RDONLY) { | 248 | error = freeze_super(sb); |
249 | sb->s_frozen = SB_FREEZE_TRANS; | 249 | if (error) { |
250 | up_write(&sb->s_umount); | 250 | deactivate_super(sb); |
251 | bdev->bd_fsfreeze_count--; | ||
251 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 252 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
252 | return sb; | 253 | return ERR_PTR(error); |
253 | } | ||
254 | |||
255 | sb->s_frozen = SB_FREEZE_WRITE; | ||
256 | smp_wmb(); | ||
257 | |||
258 | sync_filesystem(sb); | ||
259 | |||
260 | sb->s_frozen = SB_FREEZE_TRANS; | ||
261 | smp_wmb(); | ||
262 | |||
263 | sync_blockdev(sb->s_bdev); | ||
264 | |||
265 | if (sb->s_op->freeze_fs) { | ||
266 | error = sb->s_op->freeze_fs(sb); | ||
267 | if (error) { | ||
268 | printk(KERN_ERR | ||
269 | "VFS:Filesystem freeze failed\n"); | ||
270 | sb->s_frozen = SB_UNFROZEN; | ||
271 | deactivate_locked_super(sb); | ||
272 | bdev->bd_fsfreeze_count--; | ||
273 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
274 | return ERR_PTR(error); | ||
275 | } | ||
276 | } | 254 | } |
277 | up_write(&sb->s_umount); | 255 | deactivate_super(sb); |
278 | |||
279 | out: | 256 | out: |
280 | sync_blockdev(bdev); | 257 | sync_blockdev(bdev); |
281 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 258 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
@@ -296,40 +273,22 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
296 | 273 | ||
297 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 274 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
298 | if (!bdev->bd_fsfreeze_count) | 275 | if (!bdev->bd_fsfreeze_count) |
299 | goto out_unlock; | 276 | goto out; |
300 | 277 | ||
301 | error = 0; | 278 | error = 0; |
302 | if (--bdev->bd_fsfreeze_count > 0) | 279 | if (--bdev->bd_fsfreeze_count > 0) |
303 | goto out_unlock; | 280 | goto out; |
304 | 281 | ||
305 | if (!sb) | 282 | if (!sb) |
306 | goto out_unlock; | 283 | goto out; |
307 | |||
308 | BUG_ON(sb->s_bdev != bdev); | ||
309 | down_write(&sb->s_umount); | ||
310 | if (sb->s_flags & MS_RDONLY) | ||
311 | goto out_unfrozen; | ||
312 | |||
313 | if (sb->s_op->unfreeze_fs) { | ||
314 | error = sb->s_op->unfreeze_fs(sb); | ||
315 | if (error) { | ||
316 | printk(KERN_ERR | ||
317 | "VFS:Filesystem thaw failed\n"); | ||
318 | sb->s_frozen = SB_FREEZE_TRANS; | ||
319 | bdev->bd_fsfreeze_count++; | ||
320 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
321 | return error; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | out_unfrozen: | ||
326 | sb->s_frozen = SB_UNFROZEN; | ||
327 | smp_wmb(); | ||
328 | wake_up(&sb->s_wait_unfrozen); | ||
329 | 284 | ||
330 | if (sb) | 285 | error = thaw_super(sb); |
331 | deactivate_locked_super(sb); | 286 | if (error) { |
332 | out_unlock: | 287 | bdev->bd_fsfreeze_count++; |
288 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | ||
289 | return error; | ||
290 | } | ||
291 | out: | ||
333 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 292 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
334 | return 0; | 293 | return 0; |
335 | } | 294 | } |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 6ef7b26724ec..8d432cd9d580 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -282,14 +282,14 @@ int btrfs_acl_chmod(struct inode *inode) | |||
282 | return ret; | 282 | return ret; |
283 | } | 283 | } |
284 | 284 | ||
285 | struct xattr_handler btrfs_xattr_acl_default_handler = { | 285 | const struct xattr_handler btrfs_xattr_acl_default_handler = { |
286 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 286 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
287 | .flags = ACL_TYPE_DEFAULT, | 287 | .flags = ACL_TYPE_DEFAULT, |
288 | .get = btrfs_xattr_acl_get, | 288 | .get = btrfs_xattr_acl_get, |
289 | .set = btrfs_xattr_acl_set, | 289 | .set = btrfs_xattr_acl_set, |
290 | }; | 290 | }; |
291 | 291 | ||
292 | struct xattr_handler btrfs_xattr_acl_access_handler = { | 292 | const struct xattr_handler btrfs_xattr_acl_access_handler = { |
293 | .prefix = POSIX_ACL_XATTR_ACCESS, | 293 | .prefix = POSIX_ACL_XATTR_ACCESS, |
294 | .flags = ACL_TYPE_ACCESS, | 294 | .flags = ACL_TYPE_ACCESS, |
295 | .get = btrfs_xattr_acl_get, | 295 | .get = btrfs_xattr_acl_get, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2bfdc641d4e3..d601629b85d1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4121,16 +4121,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4121 | if (ret != 0) | 4121 | if (ret != 0) |
4122 | goto fail; | 4122 | goto fail; |
4123 | 4123 | ||
4124 | inode->i_uid = current_fsuid(); | 4124 | inode_init_owner(inode, dir, mode); |
4125 | |||
4126 | if (dir && (dir->i_mode & S_ISGID)) { | ||
4127 | inode->i_gid = dir->i_gid; | ||
4128 | if (S_ISDIR(mode)) | ||
4129 | mode |= S_ISGID; | ||
4130 | } else | ||
4131 | inode->i_gid = current_fsgid(); | ||
4132 | |||
4133 | inode->i_mode = mode; | ||
4134 | inode->i_ino = objectid; | 4125 | inode->i_ino = objectid; |
4135 | inode_set_bytes(inode, 0); | 4126 | inode_set_bytes(inode, 0); |
4136 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 4127 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 193b58f7d3f3..59acd3eb288a 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -282,7 +282,7 @@ err: | |||
282 | * List of handlers for synthetic system.* attributes. All real ondisk | 282 | * List of handlers for synthetic system.* attributes. All real ondisk |
283 | * attributes are handled directly. | 283 | * attributes are handled directly. |
284 | */ | 284 | */ |
285 | struct xattr_handler *btrfs_xattr_handlers[] = { | 285 | const struct xattr_handler *btrfs_xattr_handlers[] = { |
286 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 286 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
287 | &btrfs_xattr_acl_access_handler, | 287 | &btrfs_xattr_acl_access_handler, |
288 | &btrfs_xattr_acl_default_handler, | 288 | &btrfs_xattr_acl_default_handler, |
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index 721efa0346e0..7a43fd640bbb 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h | |||
@@ -21,9 +21,9 @@ | |||
21 | 21 | ||
22 | #include <linux/xattr.h> | 22 | #include <linux/xattr.h> |
23 | 23 | ||
24 | extern struct xattr_handler btrfs_xattr_acl_access_handler; | 24 | extern const struct xattr_handler btrfs_xattr_acl_access_handler; |
25 | extern struct xattr_handler btrfs_xattr_acl_default_handler; | 25 | extern const struct xattr_handler btrfs_xattr_acl_default_handler; |
26 | extern struct xattr_handler *btrfs_xattr_handlers[]; | 26 | extern const struct xattr_handler *btrfs_xattr_handlers[]; |
27 | 27 | ||
28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | 28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, |
29 | void *buffer, size_t size); | 29 | void *buffer, size_t size); |
diff --git a/fs/buffer.c b/fs/buffer.c index 08e422d56996..e8aa7081d25c 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -561,26 +561,17 @@ repeat: | |||
561 | return err; | 561 | return err; |
562 | } | 562 | } |
563 | 563 | ||
564 | static void do_thaw_all(struct work_struct *work) | 564 | static void do_thaw_one(struct super_block *sb, void *unused) |
565 | { | 565 | { |
566 | struct super_block *sb; | ||
567 | char b[BDEVNAME_SIZE]; | 566 | char b[BDEVNAME_SIZE]; |
567 | while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb)) | ||
568 | printk(KERN_WARNING "Emergency Thaw on %s\n", | ||
569 | bdevname(sb->s_bdev, b)); | ||
570 | } | ||
568 | 571 | ||
569 | spin_lock(&sb_lock); | 572 | static void do_thaw_all(struct work_struct *work) |
570 | restart: | 573 | { |
571 | list_for_each_entry(sb, &super_blocks, s_list) { | 574 | iterate_supers(do_thaw_one, NULL); |
572 | sb->s_count++; | ||
573 | spin_unlock(&sb_lock); | ||
574 | down_read(&sb->s_umount); | ||
575 | while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb)) | ||
576 | printk(KERN_WARNING "Emergency Thaw on %s\n", | ||
577 | bdevname(sb->s_bdev, b)); | ||
578 | up_read(&sb->s_umount); | ||
579 | spin_lock(&sb_lock); | ||
580 | if (__put_super_and_need_restart(sb)) | ||
581 | goto restart; | ||
582 | } | ||
583 | spin_unlock(&sb_lock); | ||
584 | kfree(work); | 575 | kfree(work); |
585 | printk(KERN_WARNING "Emergency Thaw complete\n"); | 576 | printk(KERN_WARNING "Emergency Thaw complete\n"); |
586 | } | 577 | } |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index ed6f19721d6e..7d634938edc9 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -844,8 +844,7 @@ retry_snap: | |||
844 | if ((ret >= 0 || ret == -EIOCBQUEUED) && | 844 | if ((ret >= 0 || ret == -EIOCBQUEUED) && |
845 | ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) | 845 | ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) |
846 | || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { | 846 | || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { |
847 | err = vfs_fsync_range(file, file->f_path.dentry, | 847 | err = vfs_fsync_range(file, pos, pos + ret - 1, 1); |
848 | pos, pos + ret - 1, 1); | ||
849 | if (err < 0) | 848 | if (err < 0) |
850 | ret = err; | 849 | ret = err; |
851 | } | 850 | } |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 110857ba9269..9307bbee6fbe 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -952,8 +952,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, | |||
952 | 952 | ||
953 | out_splat: | 953 | out_splat: |
954 | ceph_mdsc_close_sessions(&client->mdsc); | 954 | ceph_mdsc_close_sessions(&client->mdsc); |
955 | up_write(&sb->s_umount); | 955 | deactivate_locked_super(sb); |
956 | deactivate_super(sb); | ||
957 | goto out_final; | 956 | goto out_final; |
958 | 957 | ||
959 | out: | 958 | out: |
diff --git a/fs/coda/file.c b/fs/coda/file.c index 4c813f2cdc52..7196077b1688 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -217,7 +217,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) | |||
217 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 217 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
218 | host_file = cfi->cfi_container; | 218 | host_file = cfi->cfi_container; |
219 | 219 | ||
220 | err = vfs_fsync(host_file, host_file->f_path.dentry, datasync); | 220 | err = vfs_fsync(host_file, datasync); |
221 | if ( !err && !datasync ) { | 221 | if ( !err && !datasync ) { |
222 | lock_kernel(); | 222 | lock_kernel(); |
223 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); | 223 | err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); |
diff --git a/fs/dcache.c b/fs/dcache.c index f1358e5c3a59..d96047b4a633 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -536,7 +536,7 @@ restart: | |||
536 | */ | 536 | */ |
537 | static void prune_dcache(int count) | 537 | static void prune_dcache(int count) |
538 | { | 538 | { |
539 | struct super_block *sb; | 539 | struct super_block *sb, *n; |
540 | int w_count; | 540 | int w_count; |
541 | int unused = dentry_stat.nr_unused; | 541 | int unused = dentry_stat.nr_unused; |
542 | int prune_ratio; | 542 | int prune_ratio; |
@@ -545,13 +545,14 @@ static void prune_dcache(int count) | |||
545 | if (unused == 0 || count == 0) | 545 | if (unused == 0 || count == 0) |
546 | return; | 546 | return; |
547 | spin_lock(&dcache_lock); | 547 | spin_lock(&dcache_lock); |
548 | restart: | ||
549 | if (count >= unused) | 548 | if (count >= unused) |
550 | prune_ratio = 1; | 549 | prune_ratio = 1; |
551 | else | 550 | else |
552 | prune_ratio = unused / count; | 551 | prune_ratio = unused / count; |
553 | spin_lock(&sb_lock); | 552 | spin_lock(&sb_lock); |
554 | list_for_each_entry(sb, &super_blocks, s_list) { | 553 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
554 | if (list_empty(&sb->s_instances)) | ||
555 | continue; | ||
555 | if (sb->s_nr_dentry_unused == 0) | 556 | if (sb->s_nr_dentry_unused == 0) |
556 | continue; | 557 | continue; |
557 | sb->s_count++; | 558 | sb->s_count++; |
@@ -590,14 +591,10 @@ restart: | |||
590 | } | 591 | } |
591 | spin_lock(&sb_lock); | 592 | spin_lock(&sb_lock); |
592 | count -= pruned; | 593 | count -= pruned; |
593 | /* | 594 | __put_super(sb); |
594 | * restart only when sb is no longer on the list and | 595 | /* more work left to do? */ |
595 | * we have more work to do. | 596 | if (count <= 0) |
596 | */ | 597 | break; |
597 | if (__put_super_and_need_restart(sb) && count > 0) { | ||
598 | spin_unlock(&sb_lock); | ||
599 | goto restart; | ||
600 | } | ||
601 | } | 598 | } |
602 | spin_unlock(&sb_lock); | 599 | spin_unlock(&sb_lock); |
603 | spin_unlock(&dcache_lock); | 600 | spin_unlock(&dcache_lock); |
@@ -1529,6 +1526,7 @@ void d_delete(struct dentry * dentry) | |||
1529 | spin_lock(&dentry->d_lock); | 1526 | spin_lock(&dentry->d_lock); |
1530 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1527 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
1531 | if (atomic_read(&dentry->d_count) == 1) { | 1528 | if (atomic_read(&dentry->d_count) == 1) { |
1529 | dentry->d_flags &= ~DCACHE_CANT_MOUNT; | ||
1532 | dentry_iput(dentry); | 1530 | dentry_iput(dentry); |
1533 | fsnotify_nameremove(dentry, isdir); | 1531 | fsnotify_nameremove(dentry, isdir); |
1534 | return; | 1532 | return; |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 0120247b41c0..8b3ffd5b5235 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -384,18 +384,15 @@ static int devpts_get_sb(struct file_system_type *fs_type, | |||
384 | s->s_flags |= MS_ACTIVE; | 384 | s->s_flags |= MS_ACTIVE; |
385 | } | 385 | } |
386 | 386 | ||
387 | simple_set_mnt(mnt, s); | ||
388 | |||
389 | memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); | 387 | memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts)); |
390 | 388 | ||
391 | error = mknod_ptmx(s); | 389 | error = mknod_ptmx(s); |
392 | if (error) | 390 | if (error) |
393 | goto out_dput; | 391 | goto out_undo_sget; |
394 | 392 | ||
395 | return 0; | 393 | simple_set_mnt(mnt, s); |
396 | 394 | ||
397 | out_dput: | 395 | return 0; |
398 | dput(s->s_root); /* undo dget() in simple_set_mnt() */ | ||
399 | 396 | ||
400 | out_undo_sget: | 397 | out_undo_sget: |
401 | deactivate_locked_super(s); | 398 | deactivate_locked_super(s); |
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 31f4b0e6d72c..83c4f600786a 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
@@ -12,7 +12,7 @@ | |||
12 | /* A global variable is a bit ugly, but it keeps the code simple */ | 12 | /* A global variable is a bit ugly, but it keeps the code simple */ |
13 | int sysctl_drop_caches; | 13 | int sysctl_drop_caches; |
14 | 14 | ||
15 | static void drop_pagecache_sb(struct super_block *sb) | 15 | static void drop_pagecache_sb(struct super_block *sb, void *unused) |
16 | { | 16 | { |
17 | struct inode *inode, *toput_inode = NULL; | 17 | struct inode *inode, *toput_inode = NULL; |
18 | 18 | ||
@@ -33,26 +33,6 @@ static void drop_pagecache_sb(struct super_block *sb) | |||
33 | iput(toput_inode); | 33 | iput(toput_inode); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void drop_pagecache(void) | ||
37 | { | ||
38 | struct super_block *sb; | ||
39 | |||
40 | spin_lock(&sb_lock); | ||
41 | restart: | ||
42 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
43 | sb->s_count++; | ||
44 | spin_unlock(&sb_lock); | ||
45 | down_read(&sb->s_umount); | ||
46 | if (sb->s_root) | ||
47 | drop_pagecache_sb(sb); | ||
48 | up_read(&sb->s_umount); | ||
49 | spin_lock(&sb_lock); | ||
50 | if (__put_super_and_need_restart(sb)) | ||
51 | goto restart; | ||
52 | } | ||
53 | spin_unlock(&sb_lock); | ||
54 | } | ||
55 | |||
56 | static void drop_slab(void) | 36 | static void drop_slab(void) |
57 | { | 37 | { |
58 | int nr_objects; | 38 | int nr_objects; |
@@ -68,7 +48,7 @@ int drop_caches_sysctl_handler(ctl_table *table, int write, | |||
68 | proc_dointvec_minmax(table, write, buffer, length, ppos); | 48 | proc_dointvec_minmax(table, write, buffer, length, ppos); |
69 | if (write) { | 49 | if (write) { |
70 | if (sysctl_drop_caches & 1) | 50 | if (sysctl_drop_caches & 1) |
71 | drop_pagecache(); | 51 | iterate_supers(drop_pagecache_sb, NULL); |
72 | if (sysctl_drop_caches & 2) | 52 | if (sysctl_drop_caches & 2) |
73 | drop_slab(); | 53 | drop_slab(); |
74 | } | 54 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index bfc2e0f78f00..0032a9f5a3a9 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -731,15 +731,14 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | |||
731 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | 731 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, |
732 | struct page *page_for_lower, | 732 | struct page *page_for_lower, |
733 | size_t offset_in_page, size_t size); | 733 | size_t offset_in_page, size_t size); |
734 | int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | 734 | int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size); |
735 | size_t size); | ||
736 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | 735 | int ecryptfs_read_lower(char *data, loff_t offset, size_t size, |
737 | struct inode *ecryptfs_inode); | 736 | struct inode *ecryptfs_inode); |
738 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | 737 | int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, |
739 | pgoff_t page_index, | 738 | pgoff_t page_index, |
740 | size_t offset_in_page, size_t size, | 739 | size_t offset_in_page, size_t size, |
741 | struct inode *ecryptfs_inode); | 740 | struct inode *ecryptfs_inode); |
742 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); | 741 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); |
743 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | 742 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); |
744 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 743 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, |
745 | struct user_namespace *user_ns); | 744 | struct user_namespace *user_ns); |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index e7440a6f5ebf..3bdddbcc785f 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -276,9 +276,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
276 | static int | 276 | static int |
277 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 277 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
278 | { | 278 | { |
279 | return vfs_fsync(ecryptfs_file_to_lower(file), | 279 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); |
280 | ecryptfs_dentry_to_lower(dentry), | ||
281 | datasync); | ||
282 | } | 280 | } |
283 | 281 | ||
284 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 282 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e2d4418affac..65dee2f336ae 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -142,19 +142,10 @@ out: | |||
142 | static int grow_file(struct dentry *ecryptfs_dentry) | 142 | static int grow_file(struct dentry *ecryptfs_dentry) |
143 | { | 143 | { |
144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | 144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
145 | struct file fake_file; | ||
146 | struct ecryptfs_file_info tmp_file_info; | ||
147 | char zero_virt[] = { 0x00 }; | 145 | char zero_virt[] = { 0x00 }; |
148 | int rc = 0; | 146 | int rc = 0; |
149 | 147 | ||
150 | memset(&fake_file, 0, sizeof(fake_file)); | 148 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); |
151 | fake_file.f_path.dentry = ecryptfs_dentry; | ||
152 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | ||
153 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | ||
154 | ecryptfs_set_file_lower( | ||
155 | &fake_file, | ||
156 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file); | ||
157 | rc = ecryptfs_write(&fake_file, zero_virt, 0, 1); | ||
158 | i_size_write(ecryptfs_inode, 0); | 149 | i_size_write(ecryptfs_inode, 0); |
159 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 150 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
160 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | 151 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= |
@@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
784 | { | 775 | { |
785 | int rc = 0; | 776 | int rc = 0; |
786 | struct inode *inode = dentry->d_inode; | 777 | struct inode *inode = dentry->d_inode; |
787 | struct dentry *lower_dentry; | ||
788 | struct file fake_ecryptfs_file; | ||
789 | struct ecryptfs_crypt_stat *crypt_stat; | 778 | struct ecryptfs_crypt_stat *crypt_stat; |
790 | loff_t i_size = i_size_read(inode); | 779 | loff_t i_size = i_size_read(inode); |
791 | loff_t lower_size_before_truncate; | 780 | loff_t lower_size_before_truncate; |
@@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
796 | goto out; | 785 | goto out; |
797 | } | 786 | } |
798 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 787 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
799 | /* Set up a fake ecryptfs file, this is used to interface with | ||
800 | * the file in the underlying filesystem so that the | ||
801 | * truncation has an effect there as well. */ | ||
802 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); | ||
803 | fake_ecryptfs_file.f_path.dentry = dentry; | ||
804 | /* Released at out_free: label */ | ||
805 | ecryptfs_set_file_private(&fake_ecryptfs_file, | ||
806 | kmem_cache_alloc(ecryptfs_file_info_cache, | ||
807 | GFP_KERNEL)); | ||
808 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | ||
809 | rc = -ENOMEM; | ||
810 | goto out; | ||
811 | } | ||
812 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
813 | ecryptfs_set_file_lower( | ||
814 | &fake_ecryptfs_file, | ||
815 | ecryptfs_inode_to_private(dentry->d_inode)->lower_file); | ||
816 | /* Switch on growing or shrinking file */ | 788 | /* Switch on growing or shrinking file */ |
817 | if (ia->ia_size > i_size) { | 789 | if (ia->ia_size > i_size) { |
818 | char zero[] = { 0x00 }; | 790 | char zero[] = { 0x00 }; |
@@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
822 | * this triggers code that will fill in 0's throughout | 794 | * this triggers code that will fill in 0's throughout |
823 | * the intermediate portion of the previous end of the | 795 | * the intermediate portion of the previous end of the |
824 | * file and the new and of the file */ | 796 | * file and the new and of the file */ |
825 | rc = ecryptfs_write(&fake_ecryptfs_file, zero, | 797 | rc = ecryptfs_write(inode, zero, |
826 | (ia->ia_size - 1), 1); | 798 | (ia->ia_size - 1), 1); |
827 | } else { /* ia->ia_size < i_size_read(inode) */ | 799 | } else { /* ia->ia_size < i_size_read(inode) */ |
828 | /* We're chopping off all the pages down to the page | 800 | /* We're chopping off all the pages down to the page |
@@ -835,10 +807,10 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
835 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
836 | rc = vmtruncate(inode, ia->ia_size); | 808 | rc = vmtruncate(inode, ia->ia_size); |
837 | if (rc) | 809 | if (rc) |
838 | goto out_free; | 810 | goto out; |
839 | lower_ia->ia_size = ia->ia_size; | 811 | lower_ia->ia_size = ia->ia_size; |
840 | lower_ia->ia_valid |= ATTR_SIZE; | 812 | lower_ia->ia_valid |= ATTR_SIZE; |
841 | goto out_free; | 813 | goto out; |
842 | } | 814 | } |
843 | if (num_zeros) { | 815 | if (num_zeros) { |
844 | char *zeros_virt; | 816 | char *zeros_virt; |
@@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
846 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); | 818 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); |
847 | if (!zeros_virt) { | 819 | if (!zeros_virt) { |
848 | rc = -ENOMEM; | 820 | rc = -ENOMEM; |
849 | goto out_free; | 821 | goto out; |
850 | } | 822 | } |
851 | rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, | 823 | rc = ecryptfs_write(inode, zeros_virt, |
852 | ia->ia_size, num_zeros); | 824 | ia->ia_size, num_zeros); |
853 | kfree(zeros_virt); | 825 | kfree(zeros_virt); |
854 | if (rc) { | 826 | if (rc) { |
855 | printk(KERN_ERR "Error attempting to zero out " | 827 | printk(KERN_ERR "Error attempting to zero out " |
856 | "the remainder of the end page on " | 828 | "the remainder of the end page on " |
857 | "reducing truncate; rc = [%d]\n", rc); | 829 | "reducing truncate; rc = [%d]\n", rc); |
858 | goto out_free; | 830 | goto out; |
859 | } | 831 | } |
860 | } | 832 | } |
861 | vmtruncate(inode, ia->ia_size); | 833 | vmtruncate(inode, ia->ia_size); |
@@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
864 | printk(KERN_ERR "Problem with " | 836 | printk(KERN_ERR "Problem with " |
865 | "ecryptfs_write_inode_size_to_metadata; " | 837 | "ecryptfs_write_inode_size_to_metadata; " |
866 | "rc = [%d]\n", rc); | 838 | "rc = [%d]\n", rc); |
867 | goto out_free; | 839 | goto out; |
868 | } | 840 | } |
869 | /* We are reducing the size of the ecryptfs file, and need to | 841 | /* We are reducing the size of the ecryptfs file, and need to |
870 | * know if we need to reduce the size of the lower file. */ | 842 | * know if we need to reduce the size of the lower file. */ |
@@ -878,10 +850,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
878 | } else | 850 | } else |
879 | lower_ia->ia_valid &= ~ATTR_SIZE; | 851 | lower_ia->ia_valid &= ~ATTR_SIZE; |
880 | } | 852 | } |
881 | out_free: | ||
882 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | ||
883 | kmem_cache_free(ecryptfs_file_info_cache, | ||
884 | ecryptfs_file_to_private(&fake_ecryptfs_file)); | ||
885 | out: | 853 | out: |
886 | return rc; | 854 | return rc; |
887 | } | 855 | } |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 760983d0f25e..cbd4e18adb20 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -281,7 +281,7 @@ static void ecryptfs_init_mount_crypt_stat( | |||
281 | * | 281 | * |
282 | * Returns zero on success; non-zero on error | 282 | * Returns zero on success; non-zero on error |
283 | */ | 283 | */ |
284 | static int ecryptfs_parse_options(struct super_block *sb, char *options) | 284 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
285 | { | 285 | { |
286 | char *p; | 286 | char *p; |
287 | int rc = 0; | 287 | int rc = 0; |
@@ -293,7 +293,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
293 | int fn_cipher_key_bytes; | 293 | int fn_cipher_key_bytes; |
294 | int fn_cipher_key_bytes_set = 0; | 294 | int fn_cipher_key_bytes_set = 0; |
295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
296 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; | 296 | &sbi->mount_crypt_stat; |
297 | substring_t args[MAX_OPT_ARGS]; | 297 | substring_t args[MAX_OPT_ARGS]; |
298 | int token; | 298 | int token; |
299 | char *sig_src; | 299 | char *sig_src; |
@@ -483,68 +483,7 @@ out: | |||
483 | } | 483 | } |
484 | 484 | ||
485 | struct kmem_cache *ecryptfs_sb_info_cache; | 485 | struct kmem_cache *ecryptfs_sb_info_cache; |
486 | 486 | static struct file_system_type ecryptfs_fs_type; | |
487 | /** | ||
488 | * ecryptfs_fill_super | ||
489 | * @sb: The ecryptfs super block | ||
490 | * @raw_data: The options passed to mount | ||
491 | * @silent: Not used but required by function prototype | ||
492 | * | ||
493 | * Sets up what we can of the sb, rest is done in ecryptfs_read_super | ||
494 | * | ||
495 | * Returns zero on success; non-zero otherwise | ||
496 | */ | ||
497 | static int | ||
498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | ||
499 | { | ||
500 | struct ecryptfs_sb_info *esi; | ||
501 | int rc = 0; | ||
502 | |||
503 | /* Released in ecryptfs_put_super() */ | ||
504 | ecryptfs_set_superblock_private(sb, | ||
505 | kmem_cache_zalloc(ecryptfs_sb_info_cache, | ||
506 | GFP_KERNEL)); | ||
507 | esi = ecryptfs_superblock_to_private(sb); | ||
508 | if (!esi) { | ||
509 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | ||
510 | rc = -ENOMEM; | ||
511 | goto out; | ||
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; | ||
519 | sb->s_op = &ecryptfs_sops; | ||
520 | /* Released through deactivate_super(sb) from get_sb_nodev */ | ||
521 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | ||
522 | .hash = 0,.name = "/",.len = 1}); | ||
523 | if (!sb->s_root) { | ||
524 | ecryptfs_printk(KERN_ERR, "d_alloc failed\n"); | ||
525 | rc = -ENOMEM; | ||
526 | goto out; | ||
527 | } | ||
528 | sb->s_root->d_op = &ecryptfs_dops; | ||
529 | sb->s_root->d_sb = sb; | ||
530 | sb->s_root->d_parent = sb->s_root; | ||
531 | /* Released in d_release when dput(sb->s_root) is called */ | ||
532 | /* through deactivate_super(sb) from get_sb_nodev() */ | ||
533 | ecryptfs_set_dentry_private(sb->s_root, | ||
534 | kmem_cache_zalloc(ecryptfs_dentry_info_cache, | ||
535 | GFP_KERNEL)); | ||
536 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | ||
537 | ecryptfs_printk(KERN_ERR, | ||
538 | "dentry_info_cache alloc failed\n"); | ||
539 | rc = -ENOMEM; | ||
540 | goto out; | ||
541 | } | ||
542 | rc = 0; | ||
543 | out: | ||
544 | /* Should be able to rely on deactivate_super called from | ||
545 | * get_sb_nodev */ | ||
546 | return rc; | ||
547 | } | ||
548 | 487 | ||
549 | /** | 488 | /** |
550 | * ecryptfs_read_super | 489 | * ecryptfs_read_super |
@@ -565,6 +504,13 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | |||
565 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); | 504 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); |
566 | goto out; | 505 | goto out; |
567 | } | 506 | } |
507 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | ||
508 | rc = -EINVAL; | ||
509 | printk(KERN_ERR "Mount on filesystem of type " | ||
510 | "eCryptfs explicitly disallowed due to " | ||
511 | "known incompatibilities\n"); | ||
512 | goto out_free; | ||
513 | } | ||
568 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); | 514 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); |
569 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 515 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
570 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; | 516 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; |
@@ -588,11 +534,8 @@ out: | |||
588 | * @dev_name: The path to mount over | 534 | * @dev_name: The path to mount over |
589 | * @raw_data: The options passed into the kernel | 535 | * @raw_data: The options passed into the kernel |
590 | * | 536 | * |
591 | * The whole ecryptfs_get_sb process is broken into 4 functions: | 537 | * The whole ecryptfs_get_sb process is broken into 3 functions: |
592 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | 538 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any |
593 | * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block | ||
594 | * with as much information as it can before needing | ||
595 | * the lower filesystem. | ||
596 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | 539 | * ecryptfs_read_super(): this accesses the lower filesystem and uses |
597 | * ecryptfs_interpose to perform most of the linking | 540 | * ecryptfs_interpose to perform most of the linking |
598 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) | 541 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) |
@@ -601,30 +544,78 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | |||
601 | const char *dev_name, void *raw_data, | 544 | const char *dev_name, void *raw_data, |
602 | struct vfsmount *mnt) | 545 | struct vfsmount *mnt) |
603 | { | 546 | { |
547 | struct super_block *s; | ||
548 | struct ecryptfs_sb_info *sbi; | ||
549 | struct ecryptfs_dentry_info *root_info; | ||
550 | const char *err = "Getting sb failed"; | ||
604 | int rc; | 551 | int rc; |
605 | struct super_block *sb; | ||
606 | 552 | ||
607 | rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt); | 553 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
608 | if (rc < 0) { | 554 | if (!sbi) { |
609 | printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc); | 555 | rc = -ENOMEM; |
610 | goto out; | 556 | goto out; |
611 | } | 557 | } |
612 | sb = mnt->mnt_sb; | 558 | |
613 | rc = ecryptfs_parse_options(sb, raw_data); | 559 | rc = ecryptfs_parse_options(sbi, raw_data); |
614 | if (rc) { | 560 | if (rc) { |
615 | printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc); | 561 | err = "Error parsing options"; |
616 | goto out_abort; | 562 | goto out; |
563 | } | ||
564 | |||
565 | s = sget(fs_type, NULL, set_anon_super, NULL); | ||
566 | if (IS_ERR(s)) { | ||
567 | rc = PTR_ERR(s); | ||
568 | goto out; | ||
617 | } | 569 | } |
618 | rc = ecryptfs_read_super(sb, dev_name); | 570 | |
571 | s->s_flags = flags; | ||
572 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
619 | if (rc) { | 573 | if (rc) { |
620 | printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc); | 574 | deactivate_locked_super(s); |
621 | goto out_abort; | 575 | goto out; |
622 | } | 576 | } |
623 | goto out; | 577 | |
624 | out_abort: | 578 | ecryptfs_set_superblock_private(s, sbi); |
625 | dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */ | 579 | s->s_bdi = &sbi->bdi; |
626 | deactivate_locked_super(sb); | 580 | |
581 | /* ->kill_sb() will take care of sbi after that point */ | ||
582 | sbi = NULL; | ||
583 | s->s_op = &ecryptfs_sops; | ||
584 | |||
585 | rc = -ENOMEM; | ||
586 | s->s_root = d_alloc(NULL, &(const struct qstr) { | ||
587 | .hash = 0,.name = "/",.len = 1}); | ||
588 | if (!s->s_root) { | ||
589 | deactivate_locked_super(s); | ||
590 | goto out; | ||
591 | } | ||
592 | s->s_root->d_op = &ecryptfs_dops; | ||
593 | s->s_root->d_sb = s; | ||
594 | s->s_root->d_parent = s->s_root; | ||
595 | |||
596 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | ||
597 | if (!root_info) { | ||
598 | deactivate_locked_super(s); | ||
599 | goto out; | ||
600 | } | ||
601 | /* ->kill_sb() will take care of root_info */ | ||
602 | ecryptfs_set_dentry_private(s->s_root, root_info); | ||
603 | s->s_flags |= MS_ACTIVE; | ||
604 | rc = ecryptfs_read_super(s, dev_name); | ||
605 | if (rc) { | ||
606 | deactivate_locked_super(s); | ||
607 | err = "Reading sb failed"; | ||
608 | goto out; | ||
609 | } | ||
610 | simple_set_mnt(mnt, s); | ||
611 | return 0; | ||
612 | |||
627 | out: | 613 | out: |
614 | if (sbi) { | ||
615 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | ||
616 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); | ||
617 | } | ||
618 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); | ||
628 | return rc; | 619 | return rc; |
629 | } | 620 | } |
630 | 621 | ||
@@ -633,11 +624,16 @@ out: | |||
633 | * @sb: The ecryptfs super block | 624 | * @sb: The ecryptfs super block |
634 | * | 625 | * |
635 | * Used to bring the superblock down and free the private data. | 626 | * Used to bring the superblock down and free the private data. |
636 | * Private data is free'd in ecryptfs_put_super() | ||
637 | */ | 627 | */ |
638 | static void ecryptfs_kill_block_super(struct super_block *sb) | 628 | static void ecryptfs_kill_block_super(struct super_block *sb) |
639 | { | 629 | { |
640 | generic_shutdown_super(sb); | 630 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); |
631 | kill_anon_super(sb); | ||
632 | if (!sb_info) | ||
633 | return; | ||
634 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
635 | bdi_destroy(&sb_info->bdi); | ||
636 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
641 | } | 637 | } |
642 | 638 | ||
643 | static struct file_system_type ecryptfs_fs_type = { | 639 | static struct file_system_type ecryptfs_fs_type = { |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 2ee9a3a7b68c..b1d82756544b 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -44,17 +44,9 @@ | |||
44 | * Returns locked and up-to-date page (if ok), with increased | 44 | * Returns locked and up-to-date page (if ok), with increased |
45 | * refcnt. | 45 | * refcnt. |
46 | */ | 46 | */ |
47 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index) | 47 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index) |
48 | { | 48 | { |
49 | struct dentry *dentry; | 49 | struct page *page = read_mapping_page(inode->i_mapping, index, NULL); |
50 | struct inode *inode; | ||
51 | struct address_space *mapping; | ||
52 | struct page *page; | ||
53 | |||
54 | dentry = file->f_path.dentry; | ||
55 | inode = dentry->d_inode; | ||
56 | mapping = inode->i_mapping; | ||
57 | page = read_mapping_page(mapping, index, (void *)file); | ||
58 | if (!IS_ERR(page)) | 50 | if (!IS_ERR(page)) |
59 | lock_page(page); | 51 | lock_page(page); |
60 | return page; | 52 | return page; |
@@ -198,7 +190,7 @@ out: | |||
198 | static int ecryptfs_readpage(struct file *file, struct page *page) | 190 | static int ecryptfs_readpage(struct file *file, struct page *page) |
199 | { | 191 | { |
200 | struct ecryptfs_crypt_stat *crypt_stat = | 192 | struct ecryptfs_crypt_stat *crypt_stat = |
201 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; | 193 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; |
202 | int rc = 0; | 194 | int rc = 0; |
203 | 195 | ||
204 | if (!crypt_stat | 196 | if (!crypt_stat |
@@ -300,8 +292,7 @@ static int ecryptfs_write_begin(struct file *file, | |||
300 | 292 | ||
301 | if (!PageUptodate(page)) { | 293 | if (!PageUptodate(page)) { |
302 | struct ecryptfs_crypt_stat *crypt_stat = | 294 | struct ecryptfs_crypt_stat *crypt_stat = |
303 | &ecryptfs_inode_to_private( | 295 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; |
304 | file->f_path.dentry->d_inode)->crypt_stat; | ||
305 | 296 | ||
306 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 297 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
307 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | 298 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
@@ -487,7 +478,7 @@ static int ecryptfs_write_end(struct file *file, | |||
487 | unsigned to = from + copied; | 478 | unsigned to = from + copied; |
488 | struct inode *ecryptfs_inode = mapping->host; | 479 | struct inode *ecryptfs_inode = mapping->host; |
489 | struct ecryptfs_crypt_stat *crypt_stat = | 480 | struct ecryptfs_crypt_stat *crypt_stat = |
490 | &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat; | 481 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
491 | int rc; | 482 | int rc; |
492 | 483 | ||
493 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { | 484 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 0cc4fafd6552..db184ef15d3d 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -93,7 +93,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | |||
93 | 93 | ||
94 | /** | 94 | /** |
95 | * ecryptfs_write | 95 | * ecryptfs_write |
96 | * @ecryptfs_file: The eCryptfs file into which to write | 96 | * @ecryptfs_inode: The eCryptfs file into which to write |
97 | * @data: Virtual address where data to write is located | 97 | * @data: Virtual address where data to write is located |
98 | * @offset: Offset in the eCryptfs file at which to begin writing the | 98 | * @offset: Offset in the eCryptfs file at which to begin writing the |
99 | * data from @data | 99 | * data from @data |
@@ -109,12 +109,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | |||
109 | * | 109 | * |
110 | * Returns zero on success; non-zero otherwise | 110 | * Returns zero on success; non-zero otherwise |
111 | */ | 111 | */ |
112 | int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | 112 | int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, |
113 | size_t size) | 113 | size_t size) |
114 | { | 114 | { |
115 | struct page *ecryptfs_page; | 115 | struct page *ecryptfs_page; |
116 | struct ecryptfs_crypt_stat *crypt_stat; | 116 | struct ecryptfs_crypt_stat *crypt_stat; |
117 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
118 | char *ecryptfs_page_virt; | 117 | char *ecryptfs_page_virt; |
119 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); | 118 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
120 | loff_t data_offset = 0; | 119 | loff_t data_offset = 0; |
@@ -145,7 +144,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
145 | if (num_bytes > total_remaining_zeros) | 144 | if (num_bytes > total_remaining_zeros) |
146 | num_bytes = total_remaining_zeros; | 145 | num_bytes = total_remaining_zeros; |
147 | } | 146 | } |
148 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, | 147 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
149 | ecryptfs_page_idx); | 148 | ecryptfs_page_idx); |
150 | if (IS_ERR(ecryptfs_page)) { | 149 | if (IS_ERR(ecryptfs_page)) { |
151 | rc = PTR_ERR(ecryptfs_page); | 150 | rc = PTR_ERR(ecryptfs_page); |
@@ -302,10 +301,10 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
302 | int ecryptfs_read(char *data, loff_t offset, size_t size, | 301 | int ecryptfs_read(char *data, loff_t offset, size_t size, |
303 | struct file *ecryptfs_file) | 302 | struct file *ecryptfs_file) |
304 | { | 303 | { |
304 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
305 | struct page *ecryptfs_page; | 305 | struct page *ecryptfs_page; |
306 | char *ecryptfs_page_virt; | 306 | char *ecryptfs_page_virt; |
307 | loff_t ecryptfs_file_size = | 307 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); |
308 | i_size_read(ecryptfs_file->f_dentry->d_inode); | ||
309 | loff_t data_offset = 0; | 308 | loff_t data_offset = 0; |
310 | loff_t pos; | 309 | loff_t pos; |
311 | int rc = 0; | 310 | int rc = 0; |
@@ -327,7 +326,7 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
327 | 326 | ||
328 | if (num_bytes > total_remaining_bytes) | 327 | if (num_bytes > total_remaining_bytes) |
329 | num_bytes = total_remaining_bytes; | 328 | num_bytes = total_remaining_bytes; |
330 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, | 329 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, |
331 | ecryptfs_page_idx); | 330 | ecryptfs_page_idx); |
332 | if (IS_ERR(ecryptfs_page)) { | 331 | if (IS_ERR(ecryptfs_page)) { |
333 | rc = PTR_ERR(ecryptfs_page); | 332 | rc = PTR_ERR(ecryptfs_page); |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 0c0ae491d231..0435886e4a9f 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -109,27 +109,6 @@ void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) | |||
109 | } | 109 | } |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * ecryptfs_put_super | ||
113 | * @sb: Pointer to the ecryptfs super block | ||
114 | * | ||
115 | * Final actions when unmounting a file system. | ||
116 | * This will handle deallocation and release of our private data. | ||
117 | */ | ||
118 | static void ecryptfs_put_super(struct super_block *sb) | ||
119 | { | ||
120 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); | ||
121 | |||
122 | lock_kernel(); | ||
123 | |||
124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
125 | bdi_destroy(&sb_info->bdi); | ||
126 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
127 | ecryptfs_set_superblock_private(sb, NULL); | ||
128 | |||
129 | unlock_kernel(); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * ecryptfs_statfs | 112 | * ecryptfs_statfs |
134 | * @sb: The ecryptfs super block | 113 | * @sb: The ecryptfs super block |
135 | * @buf: The struct kstatfs to fill in with stats | 114 | * @buf: The struct kstatfs to fill in with stats |
@@ -203,7 +182,6 @@ const struct super_operations ecryptfs_sops = { | |||
203 | .alloc_inode = ecryptfs_alloc_inode, | 182 | .alloc_inode = ecryptfs_alloc_inode, |
204 | .destroy_inode = ecryptfs_destroy_inode, | 183 | .destroy_inode = ecryptfs_destroy_inode, |
205 | .drop_inode = generic_delete_inode, | 184 | .drop_inode = generic_delete_inode, |
206 | .put_super = ecryptfs_put_super, | ||
207 | .statfs = ecryptfs_statfs, | 185 | .statfs = ecryptfs_statfs, |
208 | .remount_fs = NULL, | 186 | .remount_fs = NULL, |
209 | .clear_inode = ecryptfs_clear_inode, | 187 | .clear_inode = ecryptfs_clear_inode, |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 76d2a79ef93e..d7c6afa79754 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1123,16 +1123,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1123 | sbi = sb->s_fs_info; | 1123 | sbi = sb->s_fs_info; |
1124 | 1124 | ||
1125 | sb->s_dirt = 1; | 1125 | sb->s_dirt = 1; |
1126 | inode->i_uid = current->cred->fsuid; | 1126 | inode_init_owner(inode, dir, mode); |
1127 | if (dir->i_mode & S_ISGID) { | ||
1128 | inode->i_gid = dir->i_gid; | ||
1129 | if (S_ISDIR(mode)) | ||
1130 | mode |= S_ISGID; | ||
1131 | } else { | ||
1132 | inode->i_gid = current->cred->fsgid; | ||
1133 | } | ||
1134 | inode->i_mode = mode; | ||
1135 | |||
1136 | inode->i_ino = sbi->s_nextid++; | 1127 | inode->i_ino = sbi->s_nextid++; |
1137 | inode->i_blkbits = EXOFS_BLKSHIFT; | 1128 | inode->i_blkbits = EXOFS_BLKSHIFT; |
1138 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 1129 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index a99e54318c3d..ca7e2a0ed98a 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -420,7 +420,7 @@ release_and_out: | |||
420 | return error; | 420 | return error; |
421 | } | 421 | } |
422 | 422 | ||
423 | struct xattr_handler ext2_xattr_acl_access_handler = { | 423 | const struct xattr_handler ext2_xattr_acl_access_handler = { |
424 | .prefix = POSIX_ACL_XATTR_ACCESS, | 424 | .prefix = POSIX_ACL_XATTR_ACCESS, |
425 | .flags = ACL_TYPE_ACCESS, | 425 | .flags = ACL_TYPE_ACCESS, |
426 | .list = ext2_xattr_list_acl_access, | 426 | .list = ext2_xattr_list_acl_access, |
@@ -428,7 +428,7 @@ struct xattr_handler ext2_xattr_acl_access_handler = { | |||
428 | .set = ext2_xattr_set_acl, | 428 | .set = ext2_xattr_set_acl, |
429 | }; | 429 | }; |
430 | 430 | ||
431 | struct xattr_handler ext2_xattr_acl_default_handler = { | 431 | const struct xattr_handler ext2_xattr_acl_default_handler = { |
432 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 432 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
433 | .flags = ACL_TYPE_DEFAULT, | 433 | .flags = ACL_TYPE_DEFAULT, |
434 | .list = ext2_xattr_list_acl_default, | 434 | .list = ext2_xattr_list_acl_default, |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index f0c5286f9342..938dbc739d00 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -549,16 +549,12 @@ got: | |||
549 | 549 | ||
550 | sb->s_dirt = 1; | 550 | sb->s_dirt = 1; |
551 | mark_buffer_dirty(bh2); | 551 | mark_buffer_dirty(bh2); |
552 | inode->i_uid = current_fsuid(); | 552 | if (test_opt(sb, GRPID)) { |
553 | if (test_opt (sb, GRPID)) | 553 | inode->i_mode = mode; |
554 | inode->i_uid = current_fsuid(); | ||
554 | inode->i_gid = dir->i_gid; | 555 | inode->i_gid = dir->i_gid; |
555 | else if (dir->i_mode & S_ISGID) { | ||
556 | inode->i_gid = dir->i_gid; | ||
557 | if (S_ISDIR(mode)) | ||
558 | mode |= S_ISGID; | ||
559 | } else | 556 | } else |
560 | inode->i_gid = current_fsgid(); | 557 | inode_init_owner(inode, dir, mode); |
561 | inode->i_mode = mode; | ||
562 | 558 | ||
563 | inode->i_ino = ino; | 559 | inode->i_ino = ino; |
564 | inode->i_blocks = 0; | 560 | inode->i_blocks = 0; |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 3b96045a00ce..7c3915780b19 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -101,7 +101,7 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *, | |||
101 | 101 | ||
102 | static struct mb_cache *ext2_xattr_cache; | 102 | static struct mb_cache *ext2_xattr_cache; |
103 | 103 | ||
104 | static struct xattr_handler *ext2_xattr_handler_map[] = { | 104 | static const struct xattr_handler *ext2_xattr_handler_map[] = { |
105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, | 105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, |
106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, | 107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, |
@@ -113,7 +113,7 @@ static struct xattr_handler *ext2_xattr_handler_map[] = { | |||
113 | #endif | 113 | #endif |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct xattr_handler *ext2_xattr_handlers[] = { | 116 | const struct xattr_handler *ext2_xattr_handlers[] = { |
117 | &ext2_xattr_user_handler, | 117 | &ext2_xattr_user_handler, |
118 | &ext2_xattr_trusted_handler, | 118 | &ext2_xattr_trusted_handler, |
119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
@@ -126,10 +126,10 @@ struct xattr_handler *ext2_xattr_handlers[] = { | |||
126 | NULL | 126 | NULL |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static inline struct xattr_handler * | 129 | static inline const struct xattr_handler * |
130 | ext2_xattr_handler(int name_index) | 130 | ext2_xattr_handler(int name_index) |
131 | { | 131 | { |
132 | struct xattr_handler *handler = NULL; | 132 | const struct xattr_handler *handler = NULL; |
133 | 133 | ||
134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) | 134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) |
135 | handler = ext2_xattr_handler_map[name_index]; | 135 | handler = ext2_xattr_handler_map[name_index]; |
@@ -298,7 +298,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", | |||
298 | /* list the attribute names */ | 298 | /* list the attribute names */ |
299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); | 299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); |
300 | entry = EXT2_XATTR_NEXT(entry)) { | 300 | entry = EXT2_XATTR_NEXT(entry)) { |
301 | struct xattr_handler *handler = | 301 | const struct xattr_handler *handler = |
302 | ext2_xattr_handler(entry->e_name_index); | 302 | ext2_xattr_handler(entry->e_name_index); |
303 | 303 | ||
304 | if (handler) { | 304 | if (handler) { |
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h index bf8175b2ced9..a1a1c2184616 100644 --- a/fs/ext2/xattr.h +++ b/fs/ext2/xattr.h | |||
@@ -55,11 +55,11 @@ struct ext2_xattr_entry { | |||
55 | 55 | ||
56 | # ifdef CONFIG_EXT2_FS_XATTR | 56 | # ifdef CONFIG_EXT2_FS_XATTR |
57 | 57 | ||
58 | extern struct xattr_handler ext2_xattr_user_handler; | 58 | extern const struct xattr_handler ext2_xattr_user_handler; |
59 | extern struct xattr_handler ext2_xattr_trusted_handler; | 59 | extern const struct xattr_handler ext2_xattr_trusted_handler; |
60 | extern struct xattr_handler ext2_xattr_acl_access_handler; | 60 | extern const struct xattr_handler ext2_xattr_acl_access_handler; |
61 | extern struct xattr_handler ext2_xattr_acl_default_handler; | 61 | extern const struct xattr_handler ext2_xattr_acl_default_handler; |
62 | extern struct xattr_handler ext2_xattr_security_handler; | 62 | extern const struct xattr_handler ext2_xattr_security_handler; |
63 | 63 | ||
64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); | 64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); |
65 | 65 | ||
@@ -72,7 +72,7 @@ extern void ext2_xattr_put_super(struct super_block *); | |||
72 | extern int init_ext2_xattr(void); | 72 | extern int init_ext2_xattr(void); |
73 | extern void exit_ext2_xattr(void); | 73 | extern void exit_ext2_xattr(void); |
74 | 74 | ||
75 | extern struct xattr_handler *ext2_xattr_handlers[]; | 75 | extern const struct xattr_handler *ext2_xattr_handlers[]; |
76 | 76 | ||
77 | # else /* CONFIG_EXT2_FS_XATTR */ | 77 | # else /* CONFIG_EXT2_FS_XATTR */ |
78 | 78 | ||
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index b118c6383c6d..3004e15d5da5 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
@@ -67,7 +67,7 @@ ext2_init_security(struct inode *inode, struct inode *dir) | |||
67 | return err; | 67 | return err; |
68 | } | 68 | } |
69 | 69 | ||
70 | struct xattr_handler ext2_xattr_security_handler = { | 70 | const struct xattr_handler ext2_xattr_security_handler = { |
71 | .prefix = XATTR_SECURITY_PREFIX, | 71 | .prefix = XATTR_SECURITY_PREFIX, |
72 | .list = ext2_xattr_security_list, | 72 | .list = ext2_xattr_security_list, |
73 | .get = ext2_xattr_security_get, | 73 | .get = ext2_xattr_security_get, |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 2a26d71f4771..667e46a8d62d 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
@@ -50,7 +50,7 @@ ext2_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
50 | value, size, flags); | 50 | value, size, flags); |
51 | } | 51 | } |
52 | 52 | ||
53 | struct xattr_handler ext2_xattr_trusted_handler = { | 53 | const struct xattr_handler ext2_xattr_trusted_handler = { |
54 | .prefix = XATTR_TRUSTED_PREFIX, | 54 | .prefix = XATTR_TRUSTED_PREFIX, |
55 | .list = ext2_xattr_trusted_list, | 55 | .list = ext2_xattr_trusted_list, |
56 | .get = ext2_xattr_trusted_get, | 56 | .get = ext2_xattr_trusted_get, |
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 3f6caf3684b4..099d20f47163 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
@@ -54,7 +54,7 @@ ext2_xattr_user_set(struct dentry *dentry, const char *name, | |||
54 | name, value, size, flags); | 54 | name, value, size, flags); |
55 | } | 55 | } |
56 | 56 | ||
57 | struct xattr_handler ext2_xattr_user_handler = { | 57 | const struct xattr_handler ext2_xattr_user_handler = { |
58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
59 | .list = ext2_xattr_user_list, | 59 | .list = ext2_xattr_user_list, |
60 | .get = ext2_xattr_user_get, | 60 | .get = ext2_xattr_user_get, |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 82ba34158661..01552abbca3c 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -456,7 +456,7 @@ release_and_out: | |||
456 | return error; | 456 | return error; |
457 | } | 457 | } |
458 | 458 | ||
459 | struct xattr_handler ext3_xattr_acl_access_handler = { | 459 | const struct xattr_handler ext3_xattr_acl_access_handler = { |
460 | .prefix = POSIX_ACL_XATTR_ACCESS, | 460 | .prefix = POSIX_ACL_XATTR_ACCESS, |
461 | .flags = ACL_TYPE_ACCESS, | 461 | .flags = ACL_TYPE_ACCESS, |
462 | .list = ext3_xattr_list_acl_access, | 462 | .list = ext3_xattr_list_acl_access, |
@@ -464,7 +464,7 @@ struct xattr_handler ext3_xattr_acl_access_handler = { | |||
464 | .set = ext3_xattr_set_acl, | 464 | .set = ext3_xattr_set_acl, |
465 | }; | 465 | }; |
466 | 466 | ||
467 | struct xattr_handler ext3_xattr_acl_default_handler = { | 467 | const struct xattr_handler ext3_xattr_acl_default_handler = { |
468 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 468 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
469 | .flags = ACL_TYPE_DEFAULT, | 469 | .flags = ACL_TYPE_DEFAULT, |
470 | .list = ext3_xattr_list_acl_default, | 470 | .list = ext3_xattr_list_acl_default, |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 0d0e97ed3ff6..498021eb88fb 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -538,16 +538,13 @@ got: | |||
538 | if (S_ISDIR(mode)) | 538 | if (S_ISDIR(mode)) |
539 | percpu_counter_inc(&sbi->s_dirs_counter); | 539 | percpu_counter_inc(&sbi->s_dirs_counter); |
540 | 540 | ||
541 | inode->i_uid = current_fsuid(); | 541 | |
542 | if (test_opt (sb, GRPID)) | 542 | if (test_opt(sb, GRPID)) { |
543 | inode->i_gid = dir->i_gid; | 543 | inode->i_mode = mode; |
544 | else if (dir->i_mode & S_ISGID) { | 544 | inode->i_uid = current_fsuid(); |
545 | inode->i_gid = dir->i_gid; | 545 | inode->i_gid = dir->i_gid; |
546 | if (S_ISDIR(mode)) | ||
547 | mode |= S_ISGID; | ||
548 | } else | 546 | } else |
549 | inode->i_gid = current_fsgid(); | 547 | inode_init_owner(inode, dir, mode); |
550 | inode->i_mode = mode; | ||
551 | 548 | ||
552 | inode->i_ino = ino; | 549 | inode->i_ino = ino; |
553 | /* This is the optimal IO size (for stat), not the fs block size */ | 550 | /* This is the optimal IO size (for stat), not the fs block size */ |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 534a94c3a933..71fb8d65e54c 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -104,7 +104,7 @@ static int ext3_xattr_list(struct dentry *dentry, char *buffer, | |||
104 | 104 | ||
105 | static struct mb_cache *ext3_xattr_cache; | 105 | static struct mb_cache *ext3_xattr_cache; |
106 | 106 | ||
107 | static struct xattr_handler *ext3_xattr_handler_map[] = { | 107 | static const struct xattr_handler *ext3_xattr_handler_map[] = { |
108 | [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, | 108 | [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, |
109 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 109 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
110 | [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, | 110 | [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, |
@@ -116,7 +116,7 @@ static struct xattr_handler *ext3_xattr_handler_map[] = { | |||
116 | #endif | 116 | #endif |
117 | }; | 117 | }; |
118 | 118 | ||
119 | struct xattr_handler *ext3_xattr_handlers[] = { | 119 | const struct xattr_handler *ext3_xattr_handlers[] = { |
120 | &ext3_xattr_user_handler, | 120 | &ext3_xattr_user_handler, |
121 | &ext3_xattr_trusted_handler, | 121 | &ext3_xattr_trusted_handler, |
122 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 122 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
@@ -129,10 +129,10 @@ struct xattr_handler *ext3_xattr_handlers[] = { | |||
129 | NULL | 129 | NULL |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static inline struct xattr_handler * | 132 | static inline const struct xattr_handler * |
133 | ext3_xattr_handler(int name_index) | 133 | ext3_xattr_handler(int name_index) |
134 | { | 134 | { |
135 | struct xattr_handler *handler = NULL; | 135 | const struct xattr_handler *handler = NULL; |
136 | 136 | ||
137 | if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map)) | 137 | if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map)) |
138 | handler = ext3_xattr_handler_map[name_index]; | 138 | handler = ext3_xattr_handler_map[name_index]; |
@@ -338,7 +338,7 @@ ext3_xattr_list_entries(struct dentry *dentry, struct ext3_xattr_entry *entry, | |||
338 | size_t rest = buffer_size; | 338 | size_t rest = buffer_size; |
339 | 339 | ||
340 | for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) { | 340 | for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) { |
341 | struct xattr_handler *handler = | 341 | const struct xattr_handler *handler = |
342 | ext3_xattr_handler(entry->e_name_index); | 342 | ext3_xattr_handler(entry->e_name_index); |
343 | 343 | ||
344 | if (handler) { | 344 | if (handler) { |
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h index 148a4dfc82ab..377fe7201169 100644 --- a/fs/ext3/xattr.h +++ b/fs/ext3/xattr.h | |||
@@ -58,11 +58,11 @@ struct ext3_xattr_entry { | |||
58 | 58 | ||
59 | # ifdef CONFIG_EXT3_FS_XATTR | 59 | # ifdef CONFIG_EXT3_FS_XATTR |
60 | 60 | ||
61 | extern struct xattr_handler ext3_xattr_user_handler; | 61 | extern const struct xattr_handler ext3_xattr_user_handler; |
62 | extern struct xattr_handler ext3_xattr_trusted_handler; | 62 | extern const struct xattr_handler ext3_xattr_trusted_handler; |
63 | extern struct xattr_handler ext3_xattr_acl_access_handler; | 63 | extern const struct xattr_handler ext3_xattr_acl_access_handler; |
64 | extern struct xattr_handler ext3_xattr_acl_default_handler; | 64 | extern const struct xattr_handler ext3_xattr_acl_default_handler; |
65 | extern struct xattr_handler ext3_xattr_security_handler; | 65 | extern const struct xattr_handler ext3_xattr_security_handler; |
66 | 66 | ||
67 | extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); | 67 | extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); |
68 | 68 | ||
@@ -76,7 +76,7 @@ extern void ext3_xattr_put_super(struct super_block *); | |||
76 | extern int init_ext3_xattr(void); | 76 | extern int init_ext3_xattr(void); |
77 | extern void exit_ext3_xattr(void); | 77 | extern void exit_ext3_xattr(void); |
78 | 78 | ||
79 | extern struct xattr_handler *ext3_xattr_handlers[]; | 79 | extern const struct xattr_handler *ext3_xattr_handlers[]; |
80 | 80 | ||
81 | # else /* CONFIG_EXT3_FS_XATTR */ | 81 | # else /* CONFIG_EXT3_FS_XATTR */ |
82 | 82 | ||
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 3af91f476dff..03a99bfc59f9 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c | |||
@@ -69,7 +69,7 @@ ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | |||
69 | return err; | 69 | return err; |
70 | } | 70 | } |
71 | 71 | ||
72 | struct xattr_handler ext3_xattr_security_handler = { | 72 | const struct xattr_handler ext3_xattr_security_handler = { |
73 | .prefix = XATTR_SECURITY_PREFIX, | 73 | .prefix = XATTR_SECURITY_PREFIX, |
74 | .list = ext3_xattr_security_list, | 74 | .list = ext3_xattr_security_list, |
75 | .get = ext3_xattr_security_get, | 75 | .get = ext3_xattr_security_get, |
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index e5562845ed96..dc8edda9ffe0 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c | |||
@@ -51,7 +51,7 @@ ext3_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
51 | value, size, flags); | 51 | value, size, flags); |
52 | } | 52 | } |
53 | 53 | ||
54 | struct xattr_handler ext3_xattr_trusted_handler = { | 54 | const struct xattr_handler ext3_xattr_trusted_handler = { |
55 | .prefix = XATTR_TRUSTED_PREFIX, | 55 | .prefix = XATTR_TRUSTED_PREFIX, |
56 | .list = ext3_xattr_trusted_list, | 56 | .list = ext3_xattr_trusted_list, |
57 | .get = ext3_xattr_trusted_get, | 57 | .get = ext3_xattr_trusted_get, |
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index 3bcfe9ee0a68..7a321974d584 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c | |||
@@ -54,7 +54,7 @@ ext3_xattr_user_set(struct dentry *dentry, const char *name, | |||
54 | name, value, size, flags); | 54 | name, value, size, flags); |
55 | } | 55 | } |
56 | 56 | ||
57 | struct xattr_handler ext3_xattr_user_handler = { | 57 | const struct xattr_handler ext3_xattr_user_handler = { |
58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
59 | .list = ext3_xattr_user_list, | 59 | .list = ext3_xattr_user_list, |
60 | .get = ext3_xattr_user_get, | 60 | .get = ext3_xattr_user_get, |
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 8a2a29d35a6f..feaf498feaa6 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
@@ -454,7 +454,7 @@ release_and_out: | |||
454 | return error; | 454 | return error; |
455 | } | 455 | } |
456 | 456 | ||
457 | struct xattr_handler ext4_xattr_acl_access_handler = { | 457 | const struct xattr_handler ext4_xattr_acl_access_handler = { |
458 | .prefix = POSIX_ACL_XATTR_ACCESS, | 458 | .prefix = POSIX_ACL_XATTR_ACCESS, |
459 | .flags = ACL_TYPE_ACCESS, | 459 | .flags = ACL_TYPE_ACCESS, |
460 | .list = ext4_xattr_list_acl_access, | 460 | .list = ext4_xattr_list_acl_access, |
@@ -462,7 +462,7 @@ struct xattr_handler ext4_xattr_acl_access_handler = { | |||
462 | .set = ext4_xattr_set_acl, | 462 | .set = ext4_xattr_set_acl, |
463 | }; | 463 | }; |
464 | 464 | ||
465 | struct xattr_handler ext4_xattr_acl_default_handler = { | 465 | const struct xattr_handler ext4_xattr_acl_default_handler = { |
466 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 466 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
467 | .flags = ACL_TYPE_DEFAULT, | 467 | .flags = ACL_TYPE_DEFAULT, |
468 | .list = ext4_xattr_list_acl_default, | 468 | .list = ext4_xattr_list_acl_default, |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 57f6eef6ccd6..1a0e183a2f04 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -979,16 +979,12 @@ got: | |||
979 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); | 979 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); |
980 | } | 980 | } |
981 | 981 | ||
982 | inode->i_uid = current_fsuid(); | 982 | if (test_opt(sb, GRPID)) { |
983 | if (test_opt(sb, GRPID)) | 983 | inode->i_mode = mode; |
984 | inode->i_uid = current_fsuid(); | ||
984 | inode->i_gid = dir->i_gid; | 985 | inode->i_gid = dir->i_gid; |
985 | else if (dir->i_mode & S_ISGID) { | ||
986 | inode->i_gid = dir->i_gid; | ||
987 | if (S_ISDIR(mode)) | ||
988 | mode |= S_ISGID; | ||
989 | } else | 986 | } else |
990 | inode->i_gid = current_fsgid(); | 987 | inode_init_owner(inode, dir, mode); |
991 | inode->i_mode = mode; | ||
992 | 988 | ||
993 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); | 989 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); |
994 | /* This is the optimal IO size (for stat), not the fs block size */ | 990 | /* This is the optimal IO size (for stat), not the fs block size */ |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b4c5aa8489d8..2de0e9515089 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -97,7 +97,7 @@ static int ext4_xattr_list(struct dentry *dentry, char *buffer, | |||
97 | 97 | ||
98 | static struct mb_cache *ext4_xattr_cache; | 98 | static struct mb_cache *ext4_xattr_cache; |
99 | 99 | ||
100 | static struct xattr_handler *ext4_xattr_handler_map[] = { | 100 | static const struct xattr_handler *ext4_xattr_handler_map[] = { |
101 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, | 101 | [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, |
102 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 102 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
103 | [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, | 103 | [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, |
@@ -109,7 +109,7 @@ static struct xattr_handler *ext4_xattr_handler_map[] = { | |||
109 | #endif | 109 | #endif |
110 | }; | 110 | }; |
111 | 111 | ||
112 | struct xattr_handler *ext4_xattr_handlers[] = { | 112 | const struct xattr_handler *ext4_xattr_handlers[] = { |
113 | &ext4_xattr_user_handler, | 113 | &ext4_xattr_user_handler, |
114 | &ext4_xattr_trusted_handler, | 114 | &ext4_xattr_trusted_handler, |
115 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 115 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
@@ -122,10 +122,10 @@ struct xattr_handler *ext4_xattr_handlers[] = { | |||
122 | NULL | 122 | NULL |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static inline struct xattr_handler * | 125 | static inline const struct xattr_handler * |
126 | ext4_xattr_handler(int name_index) | 126 | ext4_xattr_handler(int name_index) |
127 | { | 127 | { |
128 | struct xattr_handler *handler = NULL; | 128 | const struct xattr_handler *handler = NULL; |
129 | 129 | ||
130 | if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) | 130 | if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map)) |
131 | handler = ext4_xattr_handler_map[name_index]; | 131 | handler = ext4_xattr_handler_map[name_index]; |
@@ -332,7 +332,7 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, | |||
332 | size_t rest = buffer_size; | 332 | size_t rest = buffer_size; |
333 | 333 | ||
334 | for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { | 334 | for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { |
335 | struct xattr_handler *handler = | 335 | const struct xattr_handler *handler = |
336 | ext4_xattr_handler(entry->e_name_index); | 336 | ext4_xattr_handler(entry->e_name_index); |
337 | 337 | ||
338 | if (handler) { | 338 | if (handler) { |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 8ede88b18c29..518e96e43905 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -65,11 +65,11 @@ struct ext4_xattr_entry { | |||
65 | 65 | ||
66 | # ifdef CONFIG_EXT4_FS_XATTR | 66 | # ifdef CONFIG_EXT4_FS_XATTR |
67 | 67 | ||
68 | extern struct xattr_handler ext4_xattr_user_handler; | 68 | extern const struct xattr_handler ext4_xattr_user_handler; |
69 | extern struct xattr_handler ext4_xattr_trusted_handler; | 69 | extern const struct xattr_handler ext4_xattr_trusted_handler; |
70 | extern struct xattr_handler ext4_xattr_acl_access_handler; | 70 | extern const struct xattr_handler ext4_xattr_acl_access_handler; |
71 | extern struct xattr_handler ext4_xattr_acl_default_handler; | 71 | extern const struct xattr_handler ext4_xattr_acl_default_handler; |
72 | extern struct xattr_handler ext4_xattr_security_handler; | 72 | extern const struct xattr_handler ext4_xattr_security_handler; |
73 | 73 | ||
74 | extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); | 74 | extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); |
75 | 75 | ||
@@ -86,7 +86,7 @@ extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
86 | extern int init_ext4_xattr(void); | 86 | extern int init_ext4_xattr(void); |
87 | extern void exit_ext4_xattr(void); | 87 | extern void exit_ext4_xattr(void); |
88 | 88 | ||
89 | extern struct xattr_handler *ext4_xattr_handlers[]; | 89 | extern const struct xattr_handler *ext4_xattr_handlers[]; |
90 | 90 | ||
91 | # else /* CONFIG_EXT4_FS_XATTR */ | 91 | # else /* CONFIG_EXT4_FS_XATTR */ |
92 | 92 | ||
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 8b145e98df07..9b21268e121c 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c | |||
@@ -69,7 +69,7 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir) | |||
69 | return err; | 69 | return err; |
70 | } | 70 | } |
71 | 71 | ||
72 | struct xattr_handler ext4_xattr_security_handler = { | 72 | const struct xattr_handler ext4_xattr_security_handler = { |
73 | .prefix = XATTR_SECURITY_PREFIX, | 73 | .prefix = XATTR_SECURITY_PREFIX, |
74 | .list = ext4_xattr_security_list, | 74 | .list = ext4_xattr_security_list, |
75 | .get = ext4_xattr_security_get, | 75 | .get = ext4_xattr_security_get, |
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index 15b50edc6587..37e6ebca2cc3 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c | |||
@@ -51,7 +51,7 @@ ext4_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
51 | name, value, size, flags); | 51 | name, value, size, flags); |
52 | } | 52 | } |
53 | 53 | ||
54 | struct xattr_handler ext4_xattr_trusted_handler = { | 54 | const struct xattr_handler ext4_xattr_trusted_handler = { |
55 | .prefix = XATTR_TRUSTED_PREFIX, | 55 | .prefix = XATTR_TRUSTED_PREFIX, |
56 | .list = ext4_xattr_trusted_list, | 56 | .list = ext4_xattr_trusted_list, |
57 | .get = ext4_xattr_trusted_get, | 57 | .get = ext4_xattr_trusted_get, |
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index c4ce05746ce1..98c375352d0e 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c | |||
@@ -54,7 +54,7 @@ ext4_xattr_user_set(struct dentry *dentry, const char *name, | |||
54 | name, value, size, flags); | 54 | name, value, size, flags); |
55 | } | 55 | } |
56 | 56 | ||
57 | struct xattr_handler ext4_xattr_user_handler = { | 57 | const struct xattr_handler ext4_xattr_user_handler = { |
58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
59 | .list = ext4_xattr_user_list, | 59 | .list = ext4_xattr_user_list, |
60 | .get = ext4_xattr_user_get, | 60 | .get = ext4_xattr_user_get, |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 437a7431b4ea..5c4161f1fd9a 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -42,10 +42,10 @@ struct wb_writeback_args { | |||
42 | long nr_pages; | 42 | long nr_pages; |
43 | struct super_block *sb; | 43 | struct super_block *sb; |
44 | enum writeback_sync_modes sync_mode; | 44 | enum writeback_sync_modes sync_mode; |
45 | int for_kupdate:1; | 45 | unsigned int for_kupdate:1; |
46 | int range_cyclic:1; | 46 | unsigned int range_cyclic:1; |
47 | int for_background:1; | 47 | unsigned int for_background:1; |
48 | int sb_pinned:1; | 48 | unsigned int sb_pinned:1; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* | 51 | /* |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index fe5df5457656..99800e564157 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
@@ -201,7 +201,7 @@ generic_check_acl(struct inode *inode, int mask) | |||
201 | return -EAGAIN; | 201 | return -EAGAIN; |
202 | } | 202 | } |
203 | 203 | ||
204 | struct xattr_handler generic_acl_access_handler = { | 204 | const struct xattr_handler generic_acl_access_handler = { |
205 | .prefix = POSIX_ACL_XATTR_ACCESS, | 205 | .prefix = POSIX_ACL_XATTR_ACCESS, |
206 | .flags = ACL_TYPE_ACCESS, | 206 | .flags = ACL_TYPE_ACCESS, |
207 | .list = generic_acl_list, | 207 | .list = generic_acl_list, |
@@ -209,7 +209,7 @@ struct xattr_handler generic_acl_access_handler = { | |||
209 | .set = generic_acl_set, | 209 | .set = generic_acl_set, |
210 | }; | 210 | }; |
211 | 211 | ||
212 | struct xattr_handler generic_acl_default_handler = { | 212 | const struct xattr_handler generic_acl_default_handler = { |
213 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 213 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
214 | .flags = ACL_TYPE_DEFAULT, | 214 | .flags = ACL_TYPE_DEFAULT, |
215 | .list = generic_acl_list, | 215 | .list = generic_acl_list, |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 87ee309d4c24..9fb76b0a0485 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -335,7 +335,7 @@ out: | |||
335 | return error; | 335 | return error; |
336 | } | 336 | } |
337 | 337 | ||
338 | struct xattr_handler gfs2_xattr_system_handler = { | 338 | const struct xattr_handler gfs2_xattr_system_handler = { |
339 | .prefix = XATTR_SYSTEM_PREFIX, | 339 | .prefix = XATTR_SYSTEM_PREFIX, |
340 | .flags = GFS2_EATYPE_SYS, | 340 | .flags = GFS2_EATYPE_SYS, |
341 | .get = gfs2_xattr_system_get, | 341 | .get = gfs2_xattr_system_get, |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 9306a2e6620c..b522b0cb39ea 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
@@ -19,6 +19,6 @@ | |||
19 | extern int gfs2_check_acl(struct inode *inode, int mask); | 19 | extern int gfs2_check_acl(struct inode *inode, int mask); |
20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); | 20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); |
21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
22 | extern struct xattr_handler gfs2_xattr_system_handler; | 22 | extern const struct xattr_handler gfs2_xattr_system_handler; |
23 | 23 | ||
24 | #endif /* __ACL_DOT_H__ */ | 24 | #endif /* __ACL_DOT_H__ */ |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 3df60f2d84e3..a0464680af0b 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -54,7 +54,7 @@ extern struct file_system_type gfs2meta_fs_type; | |||
54 | extern const struct export_operations gfs2_export_ops; | 54 | extern const struct export_operations gfs2_export_ops; |
55 | extern const struct super_operations gfs2_super_ops; | 55 | extern const struct super_operations gfs2_super_ops; |
56 | extern const struct dentry_operations gfs2_dops; | 56 | extern const struct dentry_operations gfs2_dops; |
57 | extern struct xattr_handler *gfs2_xattr_handlers[]; | 57 | extern const struct xattr_handler *gfs2_xattr_handlers[]; |
58 | 58 | ||
59 | #endif /* __SUPER_DOT_H__ */ | 59 | #endif /* __SUPER_DOT_H__ */ |
60 | 60 | ||
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index c2ebdf2c01d4..82f93da00d1b 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -1535,21 +1535,21 @@ out_alloc: | |||
1535 | return error; | 1535 | return error; |
1536 | } | 1536 | } |
1537 | 1537 | ||
1538 | static struct xattr_handler gfs2_xattr_user_handler = { | 1538 | static const struct xattr_handler gfs2_xattr_user_handler = { |
1539 | .prefix = XATTR_USER_PREFIX, | 1539 | .prefix = XATTR_USER_PREFIX, |
1540 | .flags = GFS2_EATYPE_USR, | 1540 | .flags = GFS2_EATYPE_USR, |
1541 | .get = gfs2_xattr_get, | 1541 | .get = gfs2_xattr_get, |
1542 | .set = gfs2_xattr_set, | 1542 | .set = gfs2_xattr_set, |
1543 | }; | 1543 | }; |
1544 | 1544 | ||
1545 | static struct xattr_handler gfs2_xattr_security_handler = { | 1545 | static const struct xattr_handler gfs2_xattr_security_handler = { |
1546 | .prefix = XATTR_SECURITY_PREFIX, | 1546 | .prefix = XATTR_SECURITY_PREFIX, |
1547 | .flags = GFS2_EATYPE_SECURITY, | 1547 | .flags = GFS2_EATYPE_SECURITY, |
1548 | .get = gfs2_xattr_get, | 1548 | .get = gfs2_xattr_get, |
1549 | .set = gfs2_xattr_set, | 1549 | .set = gfs2_xattr_set, |
1550 | }; | 1550 | }; |
1551 | 1551 | ||
1552 | struct xattr_handler *gfs2_xattr_handlers[] = { | 1552 | const struct xattr_handler *gfs2_xattr_handlers[] = { |
1553 | &gfs2_xattr_user_handler, | 1553 | &gfs2_xattr_user_handler, |
1554 | &gfs2_xattr_security_handler, | 1554 | &gfs2_xattr_security_handler, |
1555 | &gfs2_xattr_system_handler, | 1555 | &gfs2_xattr_system_handler, |
diff --git a/fs/inode.c b/fs/inode.c index 258ec22bb298..2bee20ae3d65 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -286,11 +286,9 @@ static void init_once(void *foo) | |||
286 | */ | 286 | */ |
287 | void __iget(struct inode *inode) | 287 | void __iget(struct inode *inode) |
288 | { | 288 | { |
289 | if (atomic_read(&inode->i_count)) { | 289 | if (atomic_inc_return(&inode->i_count) != 1) |
290 | atomic_inc(&inode->i_count); | ||
291 | return; | 290 | return; |
292 | } | 291 | |
293 | atomic_inc(&inode->i_count); | ||
294 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 292 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
295 | list_move(&inode->i_list, &inode_in_use); | 293 | list_move(&inode->i_list, &inode_in_use); |
296 | inodes_stat.nr_unused--; | 294 | inodes_stat.nr_unused--; |
@@ -1608,3 +1606,23 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) | |||
1608 | inode->i_ino); | 1606 | inode->i_ino); |
1609 | } | 1607 | } |
1610 | EXPORT_SYMBOL(init_special_inode); | 1608 | EXPORT_SYMBOL(init_special_inode); |
1609 | |||
1610 | /** | ||
1611 | * Init uid,gid,mode for new inode according to posix standards | ||
1612 | * @inode: New inode | ||
1613 | * @dir: Directory inode | ||
1614 | * @mode: mode of the new inode | ||
1615 | */ | ||
1616 | void inode_init_owner(struct inode *inode, const struct inode *dir, | ||
1617 | mode_t mode) | ||
1618 | { | ||
1619 | inode->i_uid = current_fsuid(); | ||
1620 | if (dir && dir->i_mode & S_ISGID) { | ||
1621 | inode->i_gid = dir->i_gid; | ||
1622 | if (S_ISDIR(mode)) | ||
1623 | mode |= S_ISGID; | ||
1624 | } else | ||
1625 | inode->i_gid = current_fsgid(); | ||
1626 | inode->i_mode = mode; | ||
1627 | } | ||
1628 | EXPORT_SYMBOL(inode_init_owner); | ||
diff --git a/fs/internal.h b/fs/internal.h index 8a03a5447bdf..6b706bc60a66 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -87,6 +87,8 @@ extern struct file *get_empty_filp(void); | |||
87 | * super.c | 87 | * super.c |
88 | */ | 88 | */ |
89 | extern int do_remount_sb(struct super_block *, int, void *, int); | 89 | extern int do_remount_sb(struct super_block *, int, void *, int); |
90 | extern void __put_super(struct super_block *sb); | ||
91 | extern void put_super(struct super_block *sb); | ||
90 | 92 | ||
91 | /* | 93 | /* |
92 | * open.c | 94 | * open.c |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 7faefb4da939..2d140a713861 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -525,15 +525,8 @@ static int ioctl_fsfreeze(struct file *filp) | |||
525 | if (sb->s_op->freeze_fs == NULL) | 525 | if (sb->s_op->freeze_fs == NULL) |
526 | return -EOPNOTSUPP; | 526 | return -EOPNOTSUPP; |
527 | 527 | ||
528 | /* If a blockdevice-backed filesystem isn't specified, return. */ | ||
529 | if (sb->s_bdev == NULL) | ||
530 | return -EINVAL; | ||
531 | |||
532 | /* Freeze */ | 528 | /* Freeze */ |
533 | sb = freeze_bdev(sb->s_bdev); | 529 | return freeze_super(sb); |
534 | if (IS_ERR(sb)) | ||
535 | return PTR_ERR(sb); | ||
536 | return 0; | ||
537 | } | 530 | } |
538 | 531 | ||
539 | static int ioctl_fsthaw(struct file *filp) | 532 | static int ioctl_fsthaw(struct file *filp) |
@@ -543,12 +536,8 @@ static int ioctl_fsthaw(struct file *filp) | |||
543 | if (!capable(CAP_SYS_ADMIN)) | 536 | if (!capable(CAP_SYS_ADMIN)) |
544 | return -EPERM; | 537 | return -EPERM; |
545 | 538 | ||
546 | /* If a blockdevice-backed filesystem isn't specified, return EINVAL. */ | ||
547 | if (sb->s_bdev == NULL) | ||
548 | return -EINVAL; | ||
549 | |||
550 | /* Thaw */ | 539 | /* Thaw */ |
551 | return thaw_bdev(sb->s_bdev, sb); | 540 | return thaw_super(sb); |
552 | } | 541 | } |
553 | 542 | ||
554 | /* | 543 | /* |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 7cdc3196476a..a33aab6b5e68 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -419,7 +419,7 @@ static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, | |||
419 | return rc; | 419 | return rc; |
420 | } | 420 | } |
421 | 421 | ||
422 | struct xattr_handler jffs2_acl_access_xattr_handler = { | 422 | const struct xattr_handler jffs2_acl_access_xattr_handler = { |
423 | .prefix = POSIX_ACL_XATTR_ACCESS, | 423 | .prefix = POSIX_ACL_XATTR_ACCESS, |
424 | .flags = ACL_TYPE_DEFAULT, | 424 | .flags = ACL_TYPE_DEFAULT, |
425 | .list = jffs2_acl_access_listxattr, | 425 | .list = jffs2_acl_access_listxattr, |
@@ -427,7 +427,7 @@ struct xattr_handler jffs2_acl_access_xattr_handler = { | |||
427 | .set = jffs2_acl_setxattr, | 427 | .set = jffs2_acl_setxattr, |
428 | }; | 428 | }; |
429 | 429 | ||
430 | struct xattr_handler jffs2_acl_default_xattr_handler = { | 430 | const struct xattr_handler jffs2_acl_default_xattr_handler = { |
431 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 431 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
432 | .flags = ACL_TYPE_DEFAULT, | 432 | .flags = ACL_TYPE_DEFAULT, |
433 | .list = jffs2_acl_default_listxattr, | 433 | .list = jffs2_acl_default_listxattr, |
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index f0ba63e3c36b..5e42de8d9541 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
@@ -31,8 +31,8 @@ extern int jffs2_acl_chmod(struct inode *); | |||
31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); | 31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); |
32 | extern int jffs2_init_acl_post(struct inode *); | 32 | extern int jffs2_init_acl_post(struct inode *); |
33 | 33 | ||
34 | extern struct xattr_handler jffs2_acl_access_xattr_handler; | 34 | extern const struct xattr_handler jffs2_acl_access_xattr_handler; |
35 | extern struct xattr_handler jffs2_acl_default_xattr_handler; | 35 | extern const struct xattr_handler jffs2_acl_default_xattr_handler; |
36 | 36 | ||
37 | #else | 37 | #else |
38 | 38 | ||
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index eaccee058583..239f51216a68 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
@@ -77,7 +77,7 @@ static size_t jffs2_security_listxattr(struct dentry *dentry, char *list, | |||
77 | return retlen; | 77 | return retlen; |
78 | } | 78 | } |
79 | 79 | ||
80 | struct xattr_handler jffs2_security_xattr_handler = { | 80 | const struct xattr_handler jffs2_security_xattr_handler = { |
81 | .prefix = XATTR_SECURITY_PREFIX, | 81 | .prefix = XATTR_SECURITY_PREFIX, |
82 | .list = jffs2_security_listxattr, | 82 | .list = jffs2_security_listxattr, |
83 | .set = jffs2_security_setxattr, | 83 | .set = jffs2_security_setxattr, |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 9e75c62c85d6..a2d58c96f1b4 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -904,7 +904,7 @@ struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, | |||
904 | * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) | 904 | * do_jffs2_setxattr(inode, xprefix, xname, buffer, size, flags) |
905 | * is an implementation of setxattr handler on jffs2. | 905 | * is an implementation of setxattr handler on jffs2. |
906 | * -------------------------------------------------- */ | 906 | * -------------------------------------------------- */ |
907 | struct xattr_handler *jffs2_xattr_handlers[] = { | 907 | const struct xattr_handler *jffs2_xattr_handlers[] = { |
908 | &jffs2_user_xattr_handler, | 908 | &jffs2_user_xattr_handler, |
909 | #ifdef CONFIG_JFFS2_FS_SECURITY | 909 | #ifdef CONFIG_JFFS2_FS_SECURITY |
910 | &jffs2_security_xattr_handler, | 910 | &jffs2_security_xattr_handler, |
@@ -917,8 +917,8 @@ struct xattr_handler *jffs2_xattr_handlers[] = { | |||
917 | NULL | 917 | NULL |
918 | }; | 918 | }; |
919 | 919 | ||
920 | static struct xattr_handler *xprefix_to_handler(int xprefix) { | 920 | static const struct xattr_handler *xprefix_to_handler(int xprefix) { |
921 | struct xattr_handler *ret; | 921 | const struct xattr_handler *ret; |
922 | 922 | ||
923 | switch (xprefix) { | 923 | switch (xprefix) { |
924 | case JFFS2_XPREFIX_USER: | 924 | case JFFS2_XPREFIX_USER: |
@@ -955,7 +955,7 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
955 | struct jffs2_inode_cache *ic = f->inocache; | 955 | struct jffs2_inode_cache *ic = f->inocache; |
956 | struct jffs2_xattr_ref *ref, **pref; | 956 | struct jffs2_xattr_ref *ref, **pref; |
957 | struct jffs2_xattr_datum *xd; | 957 | struct jffs2_xattr_datum *xd; |
958 | struct xattr_handler *xhandle; | 958 | const struct xattr_handler *xhandle; |
959 | ssize_t len, rc; | 959 | ssize_t len, rc; |
960 | int retry = 0; | 960 | int retry = 0; |
961 | 961 | ||
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 6e3b5ddfb7ab..cf4f5759b42b 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -93,9 +93,9 @@ extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname | |||
93 | extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, | 93 | extern int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, |
94 | const char *buffer, size_t size, int flags); | 94 | const char *buffer, size_t size, int flags); |
95 | 95 | ||
96 | extern struct xattr_handler *jffs2_xattr_handlers[]; | 96 | extern const struct xattr_handler *jffs2_xattr_handlers[]; |
97 | extern struct xattr_handler jffs2_user_xattr_handler; | 97 | extern const struct xattr_handler jffs2_user_xattr_handler; |
98 | extern struct xattr_handler jffs2_trusted_xattr_handler; | 98 | extern const struct xattr_handler jffs2_trusted_xattr_handler; |
99 | 99 | ||
100 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | 100 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); |
101 | #define jffs2_getxattr generic_getxattr | 101 | #define jffs2_getxattr generic_getxattr |
@@ -122,7 +122,7 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
122 | 122 | ||
123 | #ifdef CONFIG_JFFS2_FS_SECURITY | 123 | #ifdef CONFIG_JFFS2_FS_SECURITY |
124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir); | 124 | extern int jffs2_init_security(struct inode *inode, struct inode *dir); |
125 | extern struct xattr_handler jffs2_security_xattr_handler; | 125 | extern const struct xattr_handler jffs2_security_xattr_handler; |
126 | #else | 126 | #else |
127 | #define jffs2_init_security(inode,dir) (0) | 127 | #define jffs2_init_security(inode,dir) (0) |
128 | #endif /* CONFIG_JFFS2_FS_SECURITY */ | 128 | #endif /* CONFIG_JFFS2_FS_SECURITY */ |
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index 3e5a5e356e05..1c868194c504 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c | |||
@@ -47,7 +47,7 @@ static size_t jffs2_trusted_listxattr(struct dentry *dentry, char *list, | |||
47 | return retlen; | 47 | return retlen; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct xattr_handler jffs2_trusted_xattr_handler = { | 50 | const struct xattr_handler jffs2_trusted_xattr_handler = { |
51 | .prefix = XATTR_TRUSTED_PREFIX, | 51 | .prefix = XATTR_TRUSTED_PREFIX, |
52 | .list = jffs2_trusted_listxattr, | 52 | .list = jffs2_trusted_listxattr, |
53 | .set = jffs2_trusted_setxattr, | 53 | .set = jffs2_trusted_setxattr, |
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index 8544af67dffe..916b5c966039 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c | |||
@@ -47,7 +47,7 @@ static size_t jffs2_user_listxattr(struct dentry *dentry, char *list, | |||
47 | return retlen; | 47 | return retlen; |
48 | } | 48 | } |
49 | 49 | ||
50 | struct xattr_handler jffs2_user_xattr_handler = { | 50 | const struct xattr_handler jffs2_user_xattr_handler = { |
51 | .prefix = XATTR_USER_PREFIX, | 51 | .prefix = XATTR_USER_PREFIX, |
52 | .list = jffs2_user_listxattr, | 52 | .list = jffs2_user_listxattr, |
53 | .set = jffs2_user_setxattr, | 53 | .set = jffs2_user_setxattr, |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 829921b67765..2686531e235a 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
@@ -98,14 +98,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
98 | goto fail_unlock; | 98 | goto fail_unlock; |
99 | } | 99 | } |
100 | 100 | ||
101 | inode->i_uid = current_fsuid(); | 101 | inode_init_owner(inode, parent, mode); |
102 | if (parent->i_mode & S_ISGID) { | ||
103 | inode->i_gid = parent->i_gid; | ||
104 | if (S_ISDIR(mode)) | ||
105 | mode |= S_ISGID; | ||
106 | } else | ||
107 | inode->i_gid = current_fsgid(); | ||
108 | |||
109 | /* | 102 | /* |
110 | * New inodes need to save sane values on disk when | 103 | * New inodes need to save sane values on disk when |
111 | * uid & gid mount options are used | 104 | * uid & gid mount options are used |
@@ -121,7 +114,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
121 | if (rc) | 114 | if (rc) |
122 | goto fail_drop; | 115 | goto fail_drop; |
123 | 116 | ||
124 | inode->i_mode = mode; | ||
125 | /* inherit flags from parent */ | 117 | /* inherit flags from parent */ |
126 | jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT; | 118 | jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT; |
127 | 119 | ||
@@ -134,7 +126,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
134 | if (S_ISLNK(mode)) | 126 | if (S_ISLNK(mode)) |
135 | jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL); | 127 | jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL); |
136 | } | 128 | } |
137 | jfs_inode->mode2 |= mode; | 129 | jfs_inode->mode2 |= inode->i_mode; |
138 | 130 | ||
139 | inode->i_blocks = 0; | 131 | inode->i_blocks = 0; |
140 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 132 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 755a92e8daa7..f602e230e162 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
@@ -358,14 +358,7 @@ struct inode *logfs_new_inode(struct inode *dir, int mode) | |||
358 | inode->i_mode = mode; | 358 | inode->i_mode = mode; |
359 | logfs_set_ino_generation(sb, inode); | 359 | logfs_set_ino_generation(sb, inode); |
360 | 360 | ||
361 | inode->i_uid = current_fsuid(); | 361 | inode_init_owner(inode, dir, mode); |
362 | inode->i_gid = current_fsgid(); | ||
363 | if (dir->i_mode & S_ISGID) { | ||
364 | inode->i_gid = dir->i_gid; | ||
365 | if (S_ISDIR(mode)) | ||
366 | inode->i_mode |= S_ISGID; | ||
367 | } | ||
368 | |||
369 | logfs_inode_setops(inode); | 362 | logfs_inode_setops(inode); |
370 | insert_inode_hash(inode); | 363 | insert_inode_hash(inode); |
371 | 364 | ||
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 6ac693faae49..482779fe4e7c 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c | |||
@@ -221,7 +221,7 @@ void minix_free_inode(struct inode * inode) | |||
221 | clear_inode(inode); /* clear in-memory copy */ | 221 | clear_inode(inode); /* clear in-memory copy */ |
222 | } | 222 | } |
223 | 223 | ||
224 | struct inode * minix_new_inode(const struct inode * dir, int * error) | 224 | struct inode *minix_new_inode(const struct inode *dir, int mode, int *error) |
225 | { | 225 | { |
226 | struct super_block *sb = dir->i_sb; | 226 | struct super_block *sb = dir->i_sb; |
227 | struct minix_sb_info *sbi = minix_sb(sb); | 227 | struct minix_sb_info *sbi = minix_sb(sb); |
@@ -263,8 +263,7 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) | |||
263 | iput(inode); | 263 | iput(inode); |
264 | return NULL; | 264 | return NULL; |
265 | } | 265 | } |
266 | inode->i_uid = current_fsuid(); | 266 | inode_init_owner(inode, dir, mode); |
267 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); | ||
268 | inode->i_ino = j; | 267 | inode->i_ino = j; |
269 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 268 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
270 | inode->i_blocks = 0; | 269 | inode->i_blocks = 0; |
diff --git a/fs/minix/minix.h b/fs/minix/minix.h index 9dcf95b42116..111f34ee9e3b 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h | |||
@@ -46,7 +46,7 @@ struct minix_sb_info { | |||
46 | extern struct inode *minix_iget(struct super_block *, unsigned long); | 46 | extern struct inode *minix_iget(struct super_block *, unsigned long); |
47 | extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); | 47 | extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); |
48 | extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); | 48 | extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); |
49 | extern struct inode * minix_new_inode(const struct inode * dir, int * error); | 49 | extern struct inode * minix_new_inode(const struct inode *, int, int *); |
50 | extern void minix_free_inode(struct inode * inode); | 50 | extern void minix_free_inode(struct inode * inode); |
51 | extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); | 51 | extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); |
52 | extern int minix_new_block(struct inode * inode); | 52 | extern int minix_new_block(struct inode * inode); |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 32b131cd6121..e20ee85955d1 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -46,10 +46,9 @@ static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_ | |||
46 | if (!old_valid_dev(rdev)) | 46 | if (!old_valid_dev(rdev)) |
47 | return -EINVAL; | 47 | return -EINVAL; |
48 | 48 | ||
49 | inode = minix_new_inode(dir, &error); | 49 | inode = minix_new_inode(dir, mode, &error); |
50 | 50 | ||
51 | if (inode) { | 51 | if (inode) { |
52 | inode->i_mode = mode; | ||
53 | minix_set_inode(inode, rdev); | 52 | minix_set_inode(inode, rdev); |
54 | mark_inode_dirty(inode); | 53 | mark_inode_dirty(inode); |
55 | error = add_nondir(dentry, inode); | 54 | error = add_nondir(dentry, inode); |
@@ -73,11 +72,10 @@ static int minix_symlink(struct inode * dir, struct dentry *dentry, | |||
73 | if (i > dir->i_sb->s_blocksize) | 72 | if (i > dir->i_sb->s_blocksize) |
74 | goto out; | 73 | goto out; |
75 | 74 | ||
76 | inode = minix_new_inode(dir, &err); | 75 | inode = minix_new_inode(dir, S_IFLNK | 0777, &err); |
77 | if (!inode) | 76 | if (!inode) |
78 | goto out; | 77 | goto out; |
79 | 78 | ||
80 | inode->i_mode = S_IFLNK | 0777; | ||
81 | minix_set_inode(inode, 0); | 79 | minix_set_inode(inode, 0); |
82 | err = page_symlink(inode, symname, i); | 80 | err = page_symlink(inode, symname, i); |
83 | if (err) | 81 | if (err) |
@@ -117,13 +115,10 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) | |||
117 | 115 | ||
118 | inode_inc_link_count(dir); | 116 | inode_inc_link_count(dir); |
119 | 117 | ||
120 | inode = minix_new_inode(dir, &err); | 118 | inode = minix_new_inode(dir, mode, &err); |
121 | if (!inode) | 119 | if (!inode) |
122 | goto out_dir; | 120 | goto out_dir; |
123 | 121 | ||
124 | inode->i_mode = S_IFDIR | mode; | ||
125 | if (dir->i_mode & S_ISGID) | ||
126 | inode->i_mode |= S_ISGID; | ||
127 | minix_set_inode(inode, 0); | 122 | minix_set_inode(inode, 0); |
128 | 123 | ||
129 | inode_inc_link_count(inode); | 124 | inode_inc_link_count(inode); |
diff --git a/fs/namei.c b/fs/namei.c index b86b96fe1dc3..48e1f60520ea 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -523,9 +523,10 @@ static void path_put_conditional(struct path *path, struct nameidata *nd) | |||
523 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | 523 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) |
524 | { | 524 | { |
525 | dput(nd->path.dentry); | 525 | dput(nd->path.dentry); |
526 | if (nd->path.mnt != path->mnt) | 526 | if (nd->path.mnt != path->mnt) { |
527 | mntput(nd->path.mnt); | 527 | mntput(nd->path.mnt); |
528 | nd->path.mnt = path->mnt; | 528 | nd->path.mnt = path->mnt; |
529 | } | ||
529 | nd->path.dentry = path->dentry; | 530 | nd->path.dentry = path->dentry; |
530 | } | 531 | } |
531 | 532 | ||
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 7a9ae3254a4b..7e26caab2a26 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -44,8 +44,7 @@ | |||
44 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 44 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
45 | 45 | ||
46 | /* Globals */ | 46 | /* Globals */ |
47 | static struct path rec_dir; | 47 | static struct file *rec_file; |
48 | static int rec_dir_init = 0; | ||
49 | 48 | ||
50 | static int | 49 | static int |
51 | nfs4_save_creds(const struct cred **original_creds) | 50 | nfs4_save_creds(const struct cred **original_creds) |
@@ -117,33 +116,28 @@ out_no_tfm: | |||
117 | return status; | 116 | return status; |
118 | } | 117 | } |
119 | 118 | ||
120 | static void | ||
121 | nfsd4_sync_rec_dir(void) | ||
122 | { | ||
123 | vfs_fsync(NULL, rec_dir.dentry, 0); | ||
124 | } | ||
125 | |||
126 | int | 119 | int |
127 | nfsd4_create_clid_dir(struct nfs4_client *clp) | 120 | nfsd4_create_clid_dir(struct nfs4_client *clp) |
128 | { | 121 | { |
129 | const struct cred *original_cred; | 122 | const struct cred *original_cred; |
130 | char *dname = clp->cl_recdir; | 123 | char *dname = clp->cl_recdir; |
131 | struct dentry *dentry; | 124 | struct dentry *dir, *dentry; |
132 | int status; | 125 | int status; |
133 | 126 | ||
134 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); | 127 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); |
135 | 128 | ||
136 | if (!rec_dir_init || clp->cl_firststate) | 129 | if (!rec_file || clp->cl_firststate) |
137 | return 0; | 130 | return 0; |
138 | 131 | ||
139 | status = nfs4_save_creds(&original_cred); | 132 | status = nfs4_save_creds(&original_cred); |
140 | if (status < 0) | 133 | if (status < 0) |
141 | return status; | 134 | return status; |
142 | 135 | ||
136 | dir = rec_file->f_path.dentry; | ||
143 | /* lock the parent */ | 137 | /* lock the parent */ |
144 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); | 138 | mutex_lock(&dir->d_inode->i_mutex); |
145 | 139 | ||
146 | dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); | 140 | dentry = lookup_one_len(dname, dir, HEXDIR_LEN-1); |
147 | if (IS_ERR(dentry)) { | 141 | if (IS_ERR(dentry)) { |
148 | status = PTR_ERR(dentry); | 142 | status = PTR_ERR(dentry); |
149 | goto out_unlock; | 143 | goto out_unlock; |
@@ -153,18 +147,18 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
153 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); | 147 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); |
154 | goto out_put; | 148 | goto out_put; |
155 | } | 149 | } |
156 | status = mnt_want_write(rec_dir.mnt); | 150 | status = mnt_want_write(rec_file->f_path.mnt); |
157 | if (status) | 151 | if (status) |
158 | goto out_put; | 152 | goto out_put; |
159 | status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); | 153 | status = vfs_mkdir(dir->d_inode, dentry, S_IRWXU); |
160 | mnt_drop_write(rec_dir.mnt); | 154 | mnt_drop_write(rec_file->f_path.mnt); |
161 | out_put: | 155 | out_put: |
162 | dput(dentry); | 156 | dput(dentry); |
163 | out_unlock: | 157 | out_unlock: |
164 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); | 158 | mutex_unlock(&dir->d_inode->i_mutex); |
165 | if (status == 0) { | 159 | if (status == 0) { |
166 | clp->cl_firststate = 1; | 160 | clp->cl_firststate = 1; |
167 | nfsd4_sync_rec_dir(); | 161 | vfs_fsync(rec_file, 0); |
168 | } | 162 | } |
169 | nfs4_reset_creds(original_cred); | 163 | nfs4_reset_creds(original_cred); |
170 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); | 164 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); |
@@ -206,14 +200,14 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) | |||
206 | struct dentry *dentry; | 200 | struct dentry *dentry; |
207 | int status; | 201 | int status; |
208 | 202 | ||
209 | if (!rec_dir_init) | 203 | if (!rec_file) |
210 | return 0; | 204 | return 0; |
211 | 205 | ||
212 | status = nfs4_save_creds(&original_cred); | 206 | status = nfs4_save_creds(&original_cred); |
213 | if (status < 0) | 207 | if (status < 0) |
214 | return status; | 208 | return status; |
215 | 209 | ||
216 | filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY, | 210 | filp = dentry_open(dget(dir), mntget(rec_file->f_path.mnt), O_RDONLY, |
217 | current_cred()); | 211 | current_cred()); |
218 | status = PTR_ERR(filp); | 212 | status = PTR_ERR(filp); |
219 | if (IS_ERR(filp)) | 213 | if (IS_ERR(filp)) |
@@ -250,13 +244,14 @@ out: | |||
250 | static int | 244 | static int |
251 | nfsd4_unlink_clid_dir(char *name, int namlen) | 245 | nfsd4_unlink_clid_dir(char *name, int namlen) |
252 | { | 246 | { |
253 | struct dentry *dentry; | 247 | struct dentry *dir, *dentry; |
254 | int status; | 248 | int status; |
255 | 249 | ||
256 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); | 250 | dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); |
257 | 251 | ||
258 | mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 252 | dir = rec_file->f_path.dentry; |
259 | dentry = lookup_one_len(name, rec_dir.dentry, namlen); | 253 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
254 | dentry = lookup_one_len(name, dir, namlen); | ||
260 | if (IS_ERR(dentry)) { | 255 | if (IS_ERR(dentry)) { |
261 | status = PTR_ERR(dentry); | 256 | status = PTR_ERR(dentry); |
262 | goto out_unlock; | 257 | goto out_unlock; |
@@ -264,11 +259,11 @@ nfsd4_unlink_clid_dir(char *name, int namlen) | |||
264 | status = -ENOENT; | 259 | status = -ENOENT; |
265 | if (!dentry->d_inode) | 260 | if (!dentry->d_inode) |
266 | goto out; | 261 | goto out; |
267 | status = vfs_rmdir(rec_dir.dentry->d_inode, dentry); | 262 | status = vfs_rmdir(dir->d_inode, dentry); |
268 | out: | 263 | out: |
269 | dput(dentry); | 264 | dput(dentry); |
270 | out_unlock: | 265 | out_unlock: |
271 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); | 266 | mutex_unlock(&dir->d_inode->i_mutex); |
272 | return status; | 267 | return status; |
273 | } | 268 | } |
274 | 269 | ||
@@ -278,10 +273,10 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
278 | const struct cred *original_cred; | 273 | const struct cred *original_cred; |
279 | int status; | 274 | int status; |
280 | 275 | ||
281 | if (!rec_dir_init || !clp->cl_firststate) | 276 | if (!rec_file || !clp->cl_firststate) |
282 | return; | 277 | return; |
283 | 278 | ||
284 | status = mnt_want_write(rec_dir.mnt); | 279 | status = mnt_want_write(rec_file->f_path.mnt); |
285 | if (status) | 280 | if (status) |
286 | goto out; | 281 | goto out; |
287 | clp->cl_firststate = 0; | 282 | clp->cl_firststate = 0; |
@@ -293,8 +288,8 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
293 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); | 288 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); |
294 | nfs4_reset_creds(original_cred); | 289 | nfs4_reset_creds(original_cred); |
295 | if (status == 0) | 290 | if (status == 0) |
296 | nfsd4_sync_rec_dir(); | 291 | vfs_fsync(rec_file, 0); |
297 | mnt_drop_write(rec_dir.mnt); | 292 | mnt_drop_write(rec_file->f_path.mnt); |
298 | out: | 293 | out: |
299 | if (status) | 294 | if (status) |
300 | printk("NFSD: Failed to remove expired client state directory" | 295 | printk("NFSD: Failed to remove expired client state directory" |
@@ -323,19 +318,19 @@ void | |||
323 | nfsd4_recdir_purge_old(void) { | 318 | nfsd4_recdir_purge_old(void) { |
324 | int status; | 319 | int status; |
325 | 320 | ||
326 | if (!rec_dir_init) | 321 | if (!rec_file) |
327 | return; | 322 | return; |
328 | status = mnt_want_write(rec_dir.mnt); | 323 | status = mnt_want_write(rec_file->f_path.mnt); |
329 | if (status) | 324 | if (status) |
330 | goto out; | 325 | goto out; |
331 | status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); | 326 | status = nfsd4_list_rec_dir(rec_file->f_path.dentry, purge_old); |
332 | if (status == 0) | 327 | if (status == 0) |
333 | nfsd4_sync_rec_dir(); | 328 | vfs_fsync(rec_file, 0); |
334 | mnt_drop_write(rec_dir.mnt); | 329 | mnt_drop_write(rec_file->f_path.mnt); |
335 | out: | 330 | out: |
336 | if (status) | 331 | if (status) |
337 | printk("nfsd4: failed to purge old clients from recovery" | 332 | printk("nfsd4: failed to purge old clients from recovery" |
338 | " directory %s\n", rec_dir.dentry->d_name.name); | 333 | " directory %s\n", rec_file->f_path.dentry->d_name.name); |
339 | } | 334 | } |
340 | 335 | ||
341 | static int | 336 | static int |
@@ -355,10 +350,13 @@ int | |||
355 | nfsd4_recdir_load(void) { | 350 | nfsd4_recdir_load(void) { |
356 | int status; | 351 | int status; |
357 | 352 | ||
358 | status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir); | 353 | if (!rec_file) |
354 | return 0; | ||
355 | |||
356 | status = nfsd4_list_rec_dir(rec_file->f_path.dentry, load_recdir); | ||
359 | if (status) | 357 | if (status) |
360 | printk("nfsd4: failed loading clients from recovery" | 358 | printk("nfsd4: failed loading clients from recovery" |
361 | " directory %s\n", rec_dir.dentry->d_name.name); | 359 | " directory %s\n", rec_file->f_path.dentry->d_name.name); |
362 | return status; | 360 | return status; |
363 | } | 361 | } |
364 | 362 | ||
@@ -375,7 +373,7 @@ nfsd4_init_recdir(char *rec_dirname) | |||
375 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", | 373 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", |
376 | rec_dirname); | 374 | rec_dirname); |
377 | 375 | ||
378 | BUG_ON(rec_dir_init); | 376 | BUG_ON(rec_file); |
379 | 377 | ||
380 | status = nfs4_save_creds(&original_cred); | 378 | status = nfs4_save_creds(&original_cred); |
381 | if (status < 0) { | 379 | if (status < 0) { |
@@ -385,22 +383,21 @@ nfsd4_init_recdir(char *rec_dirname) | |||
385 | return; | 383 | return; |
386 | } | 384 | } |
387 | 385 | ||
388 | status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, | 386 | rec_file = filp_open(rec_dirname, O_RDONLY | O_DIRECTORY, 0); |
389 | &rec_dir); | 387 | if (IS_ERR(rec_file)) { |
390 | if (status) | ||
391 | printk("NFSD: unable to find recovery directory %s\n", | 388 | printk("NFSD: unable to find recovery directory %s\n", |
392 | rec_dirname); | 389 | rec_dirname); |
390 | rec_file = NULL; | ||
391 | } | ||
393 | 392 | ||
394 | if (!status) | ||
395 | rec_dir_init = 1; | ||
396 | nfs4_reset_creds(original_cred); | 393 | nfs4_reset_creds(original_cred); |
397 | } | 394 | } |
398 | 395 | ||
399 | void | 396 | void |
400 | nfsd4_shutdown_recdir(void) | 397 | nfsd4_shutdown_recdir(void) |
401 | { | 398 | { |
402 | if (!rec_dir_init) | 399 | if (!rec_file) |
403 | return; | 400 | return; |
404 | rec_dir_init = 0; | 401 | fput(rec_file); |
405 | path_put(&rec_dir); | 402 | rec_file = NULL; |
406 | } | 403 | } |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 23c06f77f4ca..ebbf3b6b2457 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -999,7 +999,7 @@ static int wait_for_concurrent_writes(struct file *file) | |||
999 | 999 | ||
1000 | if (inode->i_state & I_DIRTY) { | 1000 | if (inode->i_state & I_DIRTY) { |
1001 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); | 1001 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); |
1002 | err = vfs_fsync(file, file->f_path.dentry, 0); | 1002 | err = vfs_fsync(file, 0); |
1003 | } | 1003 | } |
1004 | last_ino = inode->i_ino; | 1004 | last_ino = inode->i_ino; |
1005 | last_dev = inode->i_sb->s_dev; | 1005 | last_dev = inode->i_sb->s_dev; |
@@ -1175,8 +1175,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1175 | if (err) | 1175 | if (err) |
1176 | goto out; | 1176 | goto out; |
1177 | if (EX_ISSYNC(fhp->fh_export)) { | 1177 | if (EX_ISSYNC(fhp->fh_export)) { |
1178 | int err2 = vfs_fsync_range(file, file->f_path.dentry, | 1178 | int err2 = vfs_fsync_range(file, offset, end, 0); |
1179 | offset, end, 0); | ||
1180 | 1179 | ||
1181 | if (err2 != -EINVAL) | 1180 | if (err2 != -EINVAL) |
1182 | err = nfserrno(err2); | 1181 | err = nfserrno(err2); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 5e226d4b41d3..39e038ac8fcb 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -280,16 +280,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
280 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ | 280 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ |
281 | 281 | ||
282 | atomic_inc(&sbi->s_inodes_count); | 282 | atomic_inc(&sbi->s_inodes_count); |
283 | 283 | inode_init_owner(inode, dir, mode); | |
284 | inode->i_uid = current_fsuid(); | ||
285 | if (dir->i_mode & S_ISGID) { | ||
286 | inode->i_gid = dir->i_gid; | ||
287 | if (S_ISDIR(mode)) | ||
288 | mode |= S_ISGID; | ||
289 | } else | ||
290 | inode->i_gid = current_fsgid(); | ||
291 | |||
292 | inode->i_mode = mode; | ||
293 | inode->i_ino = ino; | 284 | inode->i_ino = ino; |
294 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 285 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
295 | 286 | ||
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index 40b1cf914ccb..27b75ebc7460 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
@@ -110,14 +110,10 @@ EXPORT_SYMBOL_GPL(get_inotify_watch); | |||
110 | int pin_inotify_watch(struct inotify_watch *watch) | 110 | int pin_inotify_watch(struct inotify_watch *watch) |
111 | { | 111 | { |
112 | struct super_block *sb = watch->inode->i_sb; | 112 | struct super_block *sb = watch->inode->i_sb; |
113 | spin_lock(&sb_lock); | 113 | if (atomic_inc_not_zero(&sb->s_active)) { |
114 | if (sb->s_count >= S_BIAS) { | ||
115 | atomic_inc(&sb->s_active); | ||
116 | spin_unlock(&sb_lock); | ||
117 | atomic_inc(&watch->count); | 114 | atomic_inc(&watch->count); |
118 | return 1; | 115 | return 1; |
119 | } | 116 | } |
120 | spin_unlock(&sb_lock); | ||
121 | return 0; | 117 | return 0; |
122 | } | 118 | } |
123 | 119 | ||
@@ -515,34 +511,8 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
515 | * done. Cleanup is just deactivate_super(). However, that leaves a messy | 511 | * done. Cleanup is just deactivate_super(). However, that leaves a messy |
516 | * case - what if we *are* racing with umount() and active references to | 512 | * case - what if we *are* racing with umount() and active references to |
517 | * superblock can't be acquired anymore? We can bump ->s_count, grab | 513 | * superblock can't be acquired anymore? We can bump ->s_count, grab |
518 | * ->s_umount, which will almost certainly wait until the superblock is shut | 514 | * ->s_umount, which will wait until the superblock is shut down and the |
519 | * down and the watch in question is pining for fjords. That's fine, but | 515 | * watch in question is pining for fjords. |
520 | * there is a problem - we might have hit the window between ->s_active | ||
521 | * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock | ||
522 | * is past the point of no return and is heading for shutdown) and the | ||
523 | * moment when deactivate_super() acquires ->s_umount. We could just do | ||
524 | * drop_super() yield() and retry, but that's rather antisocial and this | ||
525 | * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having | ||
526 | * found that we'd got there first (i.e. that ->s_root is non-NULL) we know | ||
527 | * that we won't race with inotify_umount_inodes(). So we could grab a | ||
528 | * reference to watch and do the rest as above, just with drop_super() instead | ||
529 | * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we | ||
530 | * could grab ->s_umount. So the watch could've been gone already. | ||
531 | * | ||
532 | * That still can be dealt with - we need to save watch->wd, do idr_find() | ||
533 | * and compare its result with our pointer. If they match, we either have | ||
534 | * the damn thing still alive or we'd lost not one but two races at once, | ||
535 | * the watch had been killed and a new one got created with the same ->wd | ||
536 | * at the same address. That couldn't have happened in inotify_destroy(), | ||
537 | * but inotify_rm_wd() could run into that. Still, "new one got created" | ||
538 | * is not a problem - we have every right to kill it or leave it alone, | ||
539 | * whatever's more convenient. | ||
540 | * | ||
541 | * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as | ||
542 | * "grab it and kill it" check. If it's been our original watch, we are | ||
543 | * fine, if it's a newcomer - nevermind, just pretend that we'd won the | ||
544 | * race and kill the fscker anyway; we are safe since we know that its | ||
545 | * superblock won't be going away. | ||
546 | * | 516 | * |
547 | * And yes, this is far beyond mere "not very pretty"; so's the entire | 517 | * And yes, this is far beyond mere "not very pretty"; so's the entire |
548 | * concept of inotify to start with. | 518 | * concept of inotify to start with. |
@@ -556,57 +526,31 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
556 | * Called with ih->mutex held, drops it. Possible return values: | 526 | * Called with ih->mutex held, drops it. Possible return values: |
557 | * 0 - nothing to do, it has died | 527 | * 0 - nothing to do, it has died |
558 | * 1 - remove it, drop the reference and deactivate_super() | 528 | * 1 - remove it, drop the reference and deactivate_super() |
559 | * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid | ||
560 | * that variant, since it involved a lot of PITA, but that's the best that | ||
561 | * could've been done. | ||
562 | */ | 529 | */ |
563 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) | 530 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) |
564 | { | 531 | { |
565 | struct super_block *sb = watch->inode->i_sb; | 532 | struct super_block *sb = watch->inode->i_sb; |
566 | s32 wd = watch->wd; | ||
567 | 533 | ||
568 | spin_lock(&sb_lock); | 534 | if (atomic_inc_not_zero(&sb->s_active)) { |
569 | if (sb->s_count >= S_BIAS) { | ||
570 | atomic_inc(&sb->s_active); | ||
571 | spin_unlock(&sb_lock); | ||
572 | get_inotify_watch(watch); | 535 | get_inotify_watch(watch); |
573 | mutex_unlock(&ih->mutex); | 536 | mutex_unlock(&ih->mutex); |
574 | return 1; /* the best outcome */ | 537 | return 1; /* the best outcome */ |
575 | } | 538 | } |
539 | spin_lock(&sb_lock); | ||
576 | sb->s_count++; | 540 | sb->s_count++; |
577 | spin_unlock(&sb_lock); | 541 | spin_unlock(&sb_lock); |
578 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ | 542 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ |
579 | down_read(&sb->s_umount); | 543 | down_read(&sb->s_umount); |
580 | if (likely(!sb->s_root)) { | 544 | /* fs is already shut down; the watch is dead */ |
581 | /* fs is already shut down; the watch is dead */ | 545 | drop_super(sb); |
582 | drop_super(sb); | 546 | return 0; |
583 | return 0; | ||
584 | } | ||
585 | /* raced with the final deactivate_super() */ | ||
586 | mutex_lock(&ih->mutex); | ||
587 | if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) { | ||
588 | /* the watch is dead */ | ||
589 | mutex_unlock(&ih->mutex); | ||
590 | drop_super(sb); | ||
591 | return 0; | ||
592 | } | ||
593 | /* still alive or freed and reused with the same sb and wd; kill */ | ||
594 | get_inotify_watch(watch); | ||
595 | mutex_unlock(&ih->mutex); | ||
596 | return 2; | ||
597 | } | 547 | } |
598 | 548 | ||
599 | static void unpin_and_kill(struct inotify_watch *watch, int how) | 549 | static void unpin_and_kill(struct inotify_watch *watch) |
600 | { | 550 | { |
601 | struct super_block *sb = watch->inode->i_sb; | 551 | struct super_block *sb = watch->inode->i_sb; |
602 | put_inotify_watch(watch); | 552 | put_inotify_watch(watch); |
603 | switch (how) { | 553 | deactivate_super(sb); |
604 | case 1: | ||
605 | deactivate_super(sb); | ||
606 | break; | ||
607 | case 2: | ||
608 | drop_super(sb); | ||
609 | } | ||
610 | } | 554 | } |
611 | 555 | ||
612 | /** | 556 | /** |
@@ -628,7 +572,6 @@ void inotify_destroy(struct inotify_handle *ih) | |||
628 | struct list_head *watches; | 572 | struct list_head *watches; |
629 | struct super_block *sb; | 573 | struct super_block *sb; |
630 | struct inode *inode; | 574 | struct inode *inode; |
631 | int how; | ||
632 | 575 | ||
633 | mutex_lock(&ih->mutex); | 576 | mutex_lock(&ih->mutex); |
634 | watches = &ih->watches; | 577 | watches = &ih->watches; |
@@ -638,8 +581,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
638 | } | 581 | } |
639 | watch = list_first_entry(watches, struct inotify_watch, h_list); | 582 | watch = list_first_entry(watches, struct inotify_watch, h_list); |
640 | sb = watch->inode->i_sb; | 583 | sb = watch->inode->i_sb; |
641 | how = pin_to_kill(ih, watch); | 584 | if (!pin_to_kill(ih, watch)) |
642 | if (!how) | ||
643 | continue; | 585 | continue; |
644 | 586 | ||
645 | inode = watch->inode; | 587 | inode = watch->inode; |
@@ -654,7 +596,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
654 | 596 | ||
655 | mutex_unlock(&ih->mutex); | 597 | mutex_unlock(&ih->mutex); |
656 | mutex_unlock(&inode->inotify_mutex); | 598 | mutex_unlock(&inode->inotify_mutex); |
657 | unpin_and_kill(watch, how); | 599 | unpin_and_kill(watch); |
658 | } | 600 | } |
659 | 601 | ||
660 | /* free this handle: the put matching the get in inotify_init() */ | 602 | /* free this handle: the put matching the get in inotify_init() */ |
@@ -857,7 +799,6 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
857 | struct inotify_watch *watch; | 799 | struct inotify_watch *watch; |
858 | struct super_block *sb; | 800 | struct super_block *sb; |
859 | struct inode *inode; | 801 | struct inode *inode; |
860 | int how; | ||
861 | 802 | ||
862 | mutex_lock(&ih->mutex); | 803 | mutex_lock(&ih->mutex); |
863 | watch = idr_find(&ih->idr, wd); | 804 | watch = idr_find(&ih->idr, wd); |
@@ -866,8 +807,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
866 | return -EINVAL; | 807 | return -EINVAL; |
867 | } | 808 | } |
868 | sb = watch->inode->i_sb; | 809 | sb = watch->inode->i_sb; |
869 | how = pin_to_kill(ih, watch); | 810 | if (!pin_to_kill(ih, watch)) |
870 | if (!how) | ||
871 | return 0; | 811 | return 0; |
872 | 812 | ||
873 | inode = watch->inode; | 813 | inode = watch->inode; |
@@ -881,7 +821,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
881 | 821 | ||
882 | mutex_unlock(&ih->mutex); | 822 | mutex_unlock(&ih->mutex); |
883 | mutex_unlock(&inode->inotify_mutex); | 823 | mutex_unlock(&inode->inotify_mutex); |
884 | unpin_and_kill(watch, how); | 824 | unpin_and_kill(watch); |
885 | 825 | ||
886 | return 0; | 826 | return 0; |
887 | } | 827 | } |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index e13fc9e8fcdc..da702294d7e7 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -489,7 +489,7 @@ cleanup: | |||
489 | return ret; | 489 | return ret; |
490 | } | 490 | } |
491 | 491 | ||
492 | struct xattr_handler ocfs2_xattr_acl_access_handler = { | 492 | const struct xattr_handler ocfs2_xattr_acl_access_handler = { |
493 | .prefix = POSIX_ACL_XATTR_ACCESS, | 493 | .prefix = POSIX_ACL_XATTR_ACCESS, |
494 | .flags = ACL_TYPE_ACCESS, | 494 | .flags = ACL_TYPE_ACCESS, |
495 | .list = ocfs2_xattr_list_acl_access, | 495 | .list = ocfs2_xattr_list_acl_access, |
@@ -497,7 +497,7 @@ struct xattr_handler ocfs2_xattr_acl_access_handler = { | |||
497 | .set = ocfs2_xattr_set_acl, | 497 | .set = ocfs2_xattr_set_acl, |
498 | }; | 498 | }; |
499 | 499 | ||
500 | struct xattr_handler ocfs2_xattr_acl_default_handler = { | 500 | const struct xattr_handler ocfs2_xattr_acl_default_handler = { |
501 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 501 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
502 | .flags = ACL_TYPE_DEFAULT, | 502 | .flags = ACL_TYPE_DEFAULT, |
503 | .list = ocfs2_xattr_list_acl_default, | 503 | .list = ocfs2_xattr_list_acl_default, |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index db5dd3ed4df4..f171b51a74f7 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -204,14 +204,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode) | |||
204 | inode->i_nlink = 2; | 204 | inode->i_nlink = 2; |
205 | else | 205 | else |
206 | inode->i_nlink = 1; | 206 | inode->i_nlink = 1; |
207 | inode->i_uid = current_fsuid(); | 207 | inode_init_owner(inode, dir, mode); |
208 | if (dir->i_mode & S_ISGID) { | ||
209 | inode->i_gid = dir->i_gid; | ||
210 | if (S_ISDIR(mode)) | ||
211 | mode |= S_ISGID; | ||
212 | } else | ||
213 | inode->i_gid = current_fsgid(); | ||
214 | inode->i_mode = mode; | ||
215 | dquot_initialize(inode); | 208 | dquot_initialize(inode); |
216 | return inode; | 209 | return inode; |
217 | } | 210 | } |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 98ee6c44102d..e97b34842cfe 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -97,7 +97,7 @@ static struct ocfs2_xattr_def_value_root def_xv = { | |||
97 | .xv.xr_list.l_count = cpu_to_le16(1), | 97 | .xv.xr_list.l_count = cpu_to_le16(1), |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct xattr_handler *ocfs2_xattr_handlers[] = { | 100 | const struct xattr_handler *ocfs2_xattr_handlers[] = { |
101 | &ocfs2_xattr_user_handler, | 101 | &ocfs2_xattr_user_handler, |
102 | &ocfs2_xattr_acl_access_handler, | 102 | &ocfs2_xattr_acl_access_handler, |
103 | &ocfs2_xattr_acl_default_handler, | 103 | &ocfs2_xattr_acl_default_handler, |
@@ -106,7 +106,7 @@ struct xattr_handler *ocfs2_xattr_handlers[] = { | |||
106 | NULL | 106 | NULL |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { | 109 | static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { |
110 | [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, | 110 | [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, |
111 | [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] | 111 | [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] |
112 | = &ocfs2_xattr_acl_access_handler, | 112 | = &ocfs2_xattr_acl_access_handler, |
@@ -540,7 +540,7 @@ static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno, | |||
540 | 540 | ||
541 | static inline const char *ocfs2_xattr_prefix(int name_index) | 541 | static inline const char *ocfs2_xattr_prefix(int name_index) |
542 | { | 542 | { |
543 | struct xattr_handler *handler = NULL; | 543 | const struct xattr_handler *handler = NULL; |
544 | 544 | ||
545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) | 545 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) |
546 | handler = ocfs2_xattr_handler_map[name_index]; | 546 | handler = ocfs2_xattr_handler_map[name_index]; |
@@ -7213,7 +7213,7 @@ int ocfs2_init_security_set(handle_t *handle, | |||
7213 | xattr_ac, data_ac); | 7213 | xattr_ac, data_ac); |
7214 | } | 7214 | } |
7215 | 7215 | ||
7216 | struct xattr_handler ocfs2_xattr_security_handler = { | 7216 | const struct xattr_handler ocfs2_xattr_security_handler = { |
7217 | .prefix = XATTR_SECURITY_PREFIX, | 7217 | .prefix = XATTR_SECURITY_PREFIX, |
7218 | .list = ocfs2_xattr_security_list, | 7218 | .list = ocfs2_xattr_security_list, |
7219 | .get = ocfs2_xattr_security_get, | 7219 | .get = ocfs2_xattr_security_get, |
@@ -7257,7 +7257,7 @@ static int ocfs2_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
7257 | name, value, size, flags); | 7257 | name, value, size, flags); |
7258 | } | 7258 | } |
7259 | 7259 | ||
7260 | struct xattr_handler ocfs2_xattr_trusted_handler = { | 7260 | const struct xattr_handler ocfs2_xattr_trusted_handler = { |
7261 | .prefix = XATTR_TRUSTED_PREFIX, | 7261 | .prefix = XATTR_TRUSTED_PREFIX, |
7262 | .list = ocfs2_xattr_trusted_list, | 7262 | .list = ocfs2_xattr_trusted_list, |
7263 | .get = ocfs2_xattr_trusted_get, | 7263 | .get = ocfs2_xattr_trusted_get, |
@@ -7313,7 +7313,7 @@ static int ocfs2_xattr_user_set(struct dentry *dentry, const char *name, | |||
7313 | name, value, size, flags); | 7313 | name, value, size, flags); |
7314 | } | 7314 | } |
7315 | 7315 | ||
7316 | struct xattr_handler ocfs2_xattr_user_handler = { | 7316 | const struct xattr_handler ocfs2_xattr_user_handler = { |
7317 | .prefix = XATTR_USER_PREFIX, | 7317 | .prefix = XATTR_USER_PREFIX, |
7318 | .list = ocfs2_xattr_user_list, | 7318 | .list = ocfs2_xattr_user_list, |
7319 | .get = ocfs2_xattr_user_get, | 7319 | .get = ocfs2_xattr_user_get, |
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h index abd72a47f520..aa64bb37a65b 100644 --- a/fs/ocfs2/xattr.h +++ b/fs/ocfs2/xattr.h | |||
@@ -37,12 +37,12 @@ struct ocfs2_security_xattr_info { | |||
37 | size_t value_len; | 37 | size_t value_len; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | extern struct xattr_handler ocfs2_xattr_user_handler; | 40 | extern const struct xattr_handler ocfs2_xattr_user_handler; |
41 | extern struct xattr_handler ocfs2_xattr_trusted_handler; | 41 | extern const struct xattr_handler ocfs2_xattr_trusted_handler; |
42 | extern struct xattr_handler ocfs2_xattr_security_handler; | 42 | extern const struct xattr_handler ocfs2_xattr_security_handler; |
43 | extern struct xattr_handler ocfs2_xattr_acl_access_handler; | 43 | extern const struct xattr_handler ocfs2_xattr_acl_access_handler; |
44 | extern struct xattr_handler ocfs2_xattr_acl_default_handler; | 44 | extern const struct xattr_handler ocfs2_xattr_acl_default_handler; |
45 | extern struct xattr_handler *ocfs2_xattr_handlers[]; | 45 | extern const struct xattr_handler *ocfs2_xattr_handlers[]; |
46 | 46 | ||
47 | ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); | 47 | ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); |
48 | int ocfs2_xattr_get_nolock(struct inode *, struct buffer_head *, int, | 48 | int ocfs2_xattr_get_nolock(struct inode *, struct buffer_head *, int, |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index b44bb835e8ea..089839a6cc64 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
@@ -37,9 +37,7 @@ struct inode *omfs_new_inode(struct inode *dir, int mode) | |||
37 | goto fail; | 37 | goto fail; |
38 | 38 | ||
39 | inode->i_ino = new_block; | 39 | inode->i_ino = new_block; |
40 | inode->i_mode = mode; | 40 | inode_init_owner(inode, NULL, mode); |
41 | inode->i_uid = current_fsuid(); | ||
42 | inode->i_gid = current_fsgid(); | ||
43 | inode->i_mapping->a_ops = &omfs_aops; | 41 | inode->i_mapping->a_ops = &omfs_aops; |
44 | 42 | ||
45 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 43 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/securebits.h> | 17 | #include <linux/securebits.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <linux/vfs.h> | ||
21 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
@@ -33,171 +32,6 @@ | |||
33 | 32 | ||
34 | #include "internal.h" | 33 | #include "internal.h" |
35 | 34 | ||
36 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
37 | { | ||
38 | int retval = -ENODEV; | ||
39 | |||
40 | if (dentry) { | ||
41 | retval = -ENOSYS; | ||
42 | if (dentry->d_sb->s_op->statfs) { | ||
43 | memset(buf, 0, sizeof(*buf)); | ||
44 | retval = security_sb_statfs(dentry); | ||
45 | if (retval) | ||
46 | return retval; | ||
47 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | ||
48 | if (retval == 0 && buf->f_frsize == 0) | ||
49 | buf->f_frsize = buf->f_bsize; | ||
50 | } | ||
51 | } | ||
52 | return retval; | ||
53 | } | ||
54 | |||
55 | EXPORT_SYMBOL(vfs_statfs); | ||
56 | |||
57 | static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | ||
58 | { | ||
59 | struct kstatfs st; | ||
60 | int retval; | ||
61 | |||
62 | retval = vfs_statfs(dentry, &st); | ||
63 | if (retval) | ||
64 | return retval; | ||
65 | |||
66 | if (sizeof(*buf) == sizeof(st)) | ||
67 | memcpy(buf, &st, sizeof(st)); | ||
68 | else { | ||
69 | if (sizeof buf->f_blocks == 4) { | ||
70 | if ((st.f_blocks | st.f_bfree | st.f_bavail | | ||
71 | st.f_bsize | st.f_frsize) & | ||
72 | 0xffffffff00000000ULL) | ||
73 | return -EOVERFLOW; | ||
74 | /* | ||
75 | * f_files and f_ffree may be -1; it's okay to stuff | ||
76 | * that into 32 bits | ||
77 | */ | ||
78 | if (st.f_files != -1 && | ||
79 | (st.f_files & 0xffffffff00000000ULL)) | ||
80 | return -EOVERFLOW; | ||
81 | if (st.f_ffree != -1 && | ||
82 | (st.f_ffree & 0xffffffff00000000ULL)) | ||
83 | return -EOVERFLOW; | ||
84 | } | ||
85 | |||
86 | buf->f_type = st.f_type; | ||
87 | buf->f_bsize = st.f_bsize; | ||
88 | buf->f_blocks = st.f_blocks; | ||
89 | buf->f_bfree = st.f_bfree; | ||
90 | buf->f_bavail = st.f_bavail; | ||
91 | buf->f_files = st.f_files; | ||
92 | buf->f_ffree = st.f_ffree; | ||
93 | buf->f_fsid = st.f_fsid; | ||
94 | buf->f_namelen = st.f_namelen; | ||
95 | buf->f_frsize = st.f_frsize; | ||
96 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | ||
102 | { | ||
103 | struct kstatfs st; | ||
104 | int retval; | ||
105 | |||
106 | retval = vfs_statfs(dentry, &st); | ||
107 | if (retval) | ||
108 | return retval; | ||
109 | |||
110 | if (sizeof(*buf) == sizeof(st)) | ||
111 | memcpy(buf, &st, sizeof(st)); | ||
112 | else { | ||
113 | buf->f_type = st.f_type; | ||
114 | buf->f_bsize = st.f_bsize; | ||
115 | buf->f_blocks = st.f_blocks; | ||
116 | buf->f_bfree = st.f_bfree; | ||
117 | buf->f_bavail = st.f_bavail; | ||
118 | buf->f_files = st.f_files; | ||
119 | buf->f_ffree = st.f_ffree; | ||
120 | buf->f_fsid = st.f_fsid; | ||
121 | buf->f_namelen = st.f_namelen; | ||
122 | buf->f_frsize = st.f_frsize; | ||
123 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
124 | } | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) | ||
129 | { | ||
130 | struct path path; | ||
131 | int error; | ||
132 | |||
133 | error = user_path(pathname, &path); | ||
134 | if (!error) { | ||
135 | struct statfs tmp; | ||
136 | error = vfs_statfs_native(path.dentry, &tmp); | ||
137 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
138 | error = -EFAULT; | ||
139 | path_put(&path); | ||
140 | } | ||
141 | return error; | ||
142 | } | ||
143 | |||
144 | SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) | ||
145 | { | ||
146 | struct path path; | ||
147 | long error; | ||
148 | |||
149 | if (sz != sizeof(*buf)) | ||
150 | return -EINVAL; | ||
151 | error = user_path(pathname, &path); | ||
152 | if (!error) { | ||
153 | struct statfs64 tmp; | ||
154 | error = vfs_statfs64(path.dentry, &tmp); | ||
155 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
156 | error = -EFAULT; | ||
157 | path_put(&path); | ||
158 | } | ||
159 | return error; | ||
160 | } | ||
161 | |||
162 | SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) | ||
163 | { | ||
164 | struct file * file; | ||
165 | struct statfs tmp; | ||
166 | int error; | ||
167 | |||
168 | error = -EBADF; | ||
169 | file = fget(fd); | ||
170 | if (!file) | ||
171 | goto out; | ||
172 | error = vfs_statfs_native(file->f_path.dentry, &tmp); | ||
173 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
174 | error = -EFAULT; | ||
175 | fput(file); | ||
176 | out: | ||
177 | return error; | ||
178 | } | ||
179 | |||
180 | SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) | ||
181 | { | ||
182 | struct file * file; | ||
183 | struct statfs64 tmp; | ||
184 | int error; | ||
185 | |||
186 | if (sz != sizeof(*buf)) | ||
187 | return -EINVAL; | ||
188 | |||
189 | error = -EBADF; | ||
190 | file = fget(fd); | ||
191 | if (!file) | ||
192 | goto out; | ||
193 | error = vfs_statfs64(file->f_path.dentry, &tmp); | ||
194 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
195 | error = -EFAULT; | ||
196 | fput(file); | ||
197 | out: | ||
198 | return error; | ||
199 | } | ||
200 | |||
201 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, | 35 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, |
202 | struct file *filp) | 36 | struct file *filp) |
203 | { | 37 | { |
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c index 9e346c19bbba..9efb2cfe2410 100644 --- a/fs/partitions/efi.c +++ b/fs/partitions/efi.c | |||
@@ -626,7 +626,7 @@ int efi_partition(struct parsed_partitions *state) | |||
626 | /* If this is a RAID volume, tell md */ | 626 | /* If this is a RAID volume, tell md */ |
627 | if (!efi_guidcmp(ptes[i].partition_type_guid, | 627 | if (!efi_guidcmp(ptes[i].partition_type_guid, |
628 | PARTITION_LINUX_RAID_GUID)) | 628 | PARTITION_LINUX_RAID_GUID)) |
629 | state->parts[i+1].flags = 1; | 629 | state->parts[i + 1].flags = ADDPART_FLAG_RAID; |
630 | } | 630 | } |
631 | kfree(ptes); | 631 | kfree(ptes); |
632 | kfree(gpt); | 632 | kfree(gpt); |
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index 13e27b0082f2..74465ff7c263 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
@@ -75,7 +75,7 @@ int mac_partition(struct parsed_partitions *state) | |||
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)) | 77 | if (!strnicmp(part->type, "Linux_RAID", 10)) |
78 | state->parts[slot].flags = 1; | 78 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
79 | #ifdef CONFIG_PPC_PMAC | 79 | #ifdef CONFIG_PPC_PMAC |
80 | /* | 80 | /* |
81 | * If this is the first bootable partition, tell the | 81 | * If this is the first bootable partition, tell the |
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 645a68d8c055..15bfb7b1e044 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -498,7 +498,7 @@ int msdos_partition(struct parsed_partitions *state) | |||
498 | } | 498 | } |
499 | put_partition(state, slot, start, size); | 499 | put_partition(state, slot, start, size); |
500 | if (SYS_IND(p) == LINUX_RAID_PARTITION) | 500 | if (SYS_IND(p) == LINUX_RAID_PARTITION) |
501 | state->parts[slot].flags = 1; | 501 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
502 | if (SYS_IND(p) == DM6_PARTITION) | 502 | if (SYS_IND(p) == DM6_PARTITION) |
503 | printk("[DM]"); | 503 | printk("[DM]"); |
504 | if (SYS_IND(p) == EZD_PARTITION) | 504 | if (SYS_IND(p) == EZD_PARTITION) |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index cfc78826da90..ce3dfd066f59 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -45,36 +45,22 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd, | |||
45 | return security_quotactl(cmd, type, id, sb); | 45 | return security_quotactl(cmd, type, id, sb); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void quota_sync_one(struct super_block *sb, void *arg) | ||
49 | { | ||
50 | if (sb->s_qcop && sb->s_qcop->quota_sync) | ||
51 | sb->s_qcop->quota_sync(sb, *(int *)arg, 1); | ||
52 | } | ||
53 | |||
48 | static int quota_sync_all(int type) | 54 | static int quota_sync_all(int type) |
49 | { | 55 | { |
50 | struct super_block *sb; | ||
51 | int ret; | 56 | int ret; |
52 | 57 | ||
53 | if (type >= MAXQUOTAS) | 58 | if (type >= MAXQUOTAS) |
54 | return -EINVAL; | 59 | return -EINVAL; |
55 | ret = security_quotactl(Q_SYNC, type, 0, NULL); | 60 | ret = security_quotactl(Q_SYNC, type, 0, NULL); |
56 | if (ret) | 61 | if (!ret) |
57 | return ret; | 62 | iterate_supers(quota_sync_one, &type); |
58 | 63 | return ret; | |
59 | spin_lock(&sb_lock); | ||
60 | restart: | ||
61 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
62 | if (!sb->s_qcop || !sb->s_qcop->quota_sync) | ||
63 | continue; | ||
64 | |||
65 | sb->s_count++; | ||
66 | spin_unlock(&sb_lock); | ||
67 | down_read(&sb->s_umount); | ||
68 | if (sb->s_root) | ||
69 | sb->s_qcop->quota_sync(sb, type, 1); | ||
70 | up_read(&sb->s_umount); | ||
71 | spin_lock(&sb_lock); | ||
72 | if (__put_super_and_need_restart(sb)) | ||
73 | goto restart; | ||
74 | } | ||
75 | spin_unlock(&sb_lock); | ||
76 | |||
77 | return 0; | ||
78 | } | 64 | } |
79 | 65 | ||
80 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, | 66 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index f47cd212dee1..a5ebae70dc6d 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -52,14 +52,13 @@ static struct backing_dev_info ramfs_backing_dev_info = { | |||
52 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, | 52 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | 55 | struct inode *ramfs_get_inode(struct super_block *sb, |
56 | const struct inode *dir, int mode, dev_t dev) | ||
56 | { | 57 | { |
57 | struct inode * inode = new_inode(sb); | 58 | struct inode * inode = new_inode(sb); |
58 | 59 | ||
59 | if (inode) { | 60 | if (inode) { |
60 | inode->i_mode = mode; | 61 | inode_init_owner(inode, dir, mode); |
61 | inode->i_uid = current_fsuid(); | ||
62 | inode->i_gid = current_fsgid(); | ||
63 | inode->i_mapping->a_ops = &ramfs_aops; | 62 | inode->i_mapping->a_ops = &ramfs_aops; |
64 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | 63 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
65 | mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); | 64 | mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); |
@@ -95,15 +94,10 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
95 | static int | 94 | static int |
96 | ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | 95 | ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) |
97 | { | 96 | { |
98 | struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); | 97 | struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); |
99 | int error = -ENOSPC; | 98 | int error = -ENOSPC; |
100 | 99 | ||
101 | if (inode) { | 100 | if (inode) { |
102 | if (dir->i_mode & S_ISGID) { | ||
103 | inode->i_gid = dir->i_gid; | ||
104 | if (S_ISDIR(mode)) | ||
105 | inode->i_mode |= S_ISGID; | ||
106 | } | ||
107 | d_instantiate(dentry, inode); | 101 | d_instantiate(dentry, inode); |
108 | dget(dentry); /* Extra count - pin the dentry in core */ | 102 | dget(dentry); /* Extra count - pin the dentry in core */ |
109 | error = 0; | 103 | error = 0; |
@@ -130,13 +124,11 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * | |||
130 | struct inode *inode; | 124 | struct inode *inode; |
131 | int error = -ENOSPC; | 125 | int error = -ENOSPC; |
132 | 126 | ||
133 | inode = ramfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); | 127 | inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0); |
134 | if (inode) { | 128 | if (inode) { |
135 | int l = strlen(symname)+1; | 129 | int l = strlen(symname)+1; |
136 | error = page_symlink(inode, symname, l); | 130 | error = page_symlink(inode, symname, l); |
137 | if (!error) { | 131 | if (!error) { |
138 | if (dir->i_mode & S_ISGID) | ||
139 | inode->i_gid = dir->i_gid; | ||
140 | d_instantiate(dentry, inode); | 132 | d_instantiate(dentry, inode); |
141 | dget(dentry); | 133 | dget(dentry); |
142 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 134 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
@@ -241,7 +233,7 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
241 | sb->s_op = &ramfs_ops; | 233 | sb->s_op = &ramfs_ops; |
242 | sb->s_time_gran = 1; | 234 | sb->s_time_gran = 1; |
243 | 235 | ||
244 | inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0); | 236 | inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0); |
245 | if (!inode) { | 237 | if (!inode) { |
246 | err = -ENOMEM; | 238 | err = -ENOMEM; |
247 | goto fail; | 239 | goto fail; |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index d0c43cb99ffc..ee78d4a0086a 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -561,23 +561,13 @@ static int drop_new_inode(struct inode *inode) | |||
561 | */ | 561 | */ |
562 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) | 562 | static int new_inode_init(struct inode *inode, struct inode *dir, int mode) |
563 | { | 563 | { |
564 | |||
565 | /* the quota init calls have to know who to charge the quota to, so | ||
566 | ** we have to set uid and gid here | ||
567 | */ | ||
568 | inode->i_uid = current_fsuid(); | ||
569 | inode->i_mode = mode; | ||
570 | /* Make inode invalid - just in case we are going to drop it before | 564 | /* Make inode invalid - just in case we are going to drop it before |
571 | * the initialization happens */ | 565 | * the initialization happens */ |
572 | INODE_PKEY(inode)->k_objectid = 0; | 566 | INODE_PKEY(inode)->k_objectid = 0; |
573 | 567 | /* the quota init calls have to know who to charge the quota to, so | |
574 | if (dir->i_mode & S_ISGID) { | 568 | ** we have to set uid and gid here |
575 | inode->i_gid = dir->i_gid; | 569 | */ |
576 | if (S_ISDIR(mode)) | 570 | inode_init_owner(inode, dir, mode); |
577 | inode->i_mode |= S_ISGID; | ||
578 | } else { | ||
579 | inode->i_gid = current_fsgid(); | ||
580 | } | ||
581 | dquot_initialize(inode); | 571 | dquot_initialize(inode); |
582 | return 0; | 572 | return 0; |
583 | } | 573 | } |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e7cc00e636dc..8c4cf273c672 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -723,11 +723,11 @@ out: | |||
723 | (handler) = *(handlers)++) | 723 | (handler) = *(handlers)++) |
724 | 724 | ||
725 | /* This is the implementation for the xattr plugin infrastructure */ | 725 | /* This is the implementation for the xattr plugin infrastructure */ |
726 | static inline struct xattr_handler * | 726 | static inline const struct xattr_handler * |
727 | find_xattr_handler_prefix(struct xattr_handler **handlers, | 727 | find_xattr_handler_prefix(const struct xattr_handler **handlers, |
728 | const char *name) | 728 | const char *name) |
729 | { | 729 | { |
730 | struct xattr_handler *xah; | 730 | const struct xattr_handler *xah; |
731 | 731 | ||
732 | if (!handlers) | 732 | if (!handlers) |
733 | return NULL; | 733 | return NULL; |
@@ -748,7 +748,7 @@ ssize_t | |||
748 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | 748 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, |
749 | size_t size) | 749 | size_t size) |
750 | { | 750 | { |
751 | struct xattr_handler *handler; | 751 | const struct xattr_handler *handler; |
752 | 752 | ||
753 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 753 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
754 | 754 | ||
@@ -767,7 +767,7 @@ int | |||
767 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 767 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
768 | size_t size, int flags) | 768 | size_t size, int flags) |
769 | { | 769 | { |
770 | struct xattr_handler *handler; | 770 | const struct xattr_handler *handler; |
771 | 771 | ||
772 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 772 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
773 | 773 | ||
@@ -784,7 +784,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
784 | */ | 784 | */ |
785 | int reiserfs_removexattr(struct dentry *dentry, const char *name) | 785 | int reiserfs_removexattr(struct dentry *dentry, const char *name) |
786 | { | 786 | { |
787 | struct xattr_handler *handler; | 787 | const struct xattr_handler *handler; |
788 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); | 788 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
789 | 789 | ||
790 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) | 790 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
@@ -807,7 +807,7 @@ static int listxattr_filler(void *buf, const char *name, int namelen, | |||
807 | size_t size; | 807 | size_t size; |
808 | if (name[0] != '.' || | 808 | if (name[0] != '.' || |
809 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { | 809 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { |
810 | struct xattr_handler *handler; | 810 | const struct xattr_handler *handler; |
811 | handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, | 811 | handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, |
812 | name); | 812 | name); |
813 | if (!handler) /* Unsupported xattr name */ | 813 | if (!handler) /* Unsupported xattr name */ |
@@ -920,7 +920,7 @@ static int create_privroot(struct dentry *dentry) { return 0; } | |||
920 | #endif | 920 | #endif |
921 | 921 | ||
922 | /* Actual operations that are exported to VFS-land */ | 922 | /* Actual operations that are exported to VFS-land */ |
923 | struct xattr_handler *reiserfs_xattr_handlers[] = { | 923 | const struct xattr_handler *reiserfs_xattr_handlers[] = { |
924 | #ifdef CONFIG_REISERFS_FS_XATTR | 924 | #ifdef CONFIG_REISERFS_FS_XATTR |
925 | &reiserfs_xattr_user_handler, | 925 | &reiserfs_xattr_user_handler, |
926 | &reiserfs_xattr_trusted_handler, | 926 | &reiserfs_xattr_trusted_handler, |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 9cdb759645a9..536d697a8a28 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -500,7 +500,7 @@ static size_t posix_acl_access_list(struct dentry *dentry, char *list, | |||
500 | return size; | 500 | return size; |
501 | } | 501 | } |
502 | 502 | ||
503 | struct xattr_handler reiserfs_posix_acl_access_handler = { | 503 | const struct xattr_handler reiserfs_posix_acl_access_handler = { |
504 | .prefix = POSIX_ACL_XATTR_ACCESS, | 504 | .prefix = POSIX_ACL_XATTR_ACCESS, |
505 | .flags = ACL_TYPE_ACCESS, | 505 | .flags = ACL_TYPE_ACCESS, |
506 | .get = posix_acl_get, | 506 | .get = posix_acl_get, |
@@ -520,7 +520,7 @@ static size_t posix_acl_default_list(struct dentry *dentry, char *list, | |||
520 | return size; | 520 | return size; |
521 | } | 521 | } |
522 | 522 | ||
523 | struct xattr_handler reiserfs_posix_acl_default_handler = { | 523 | const struct xattr_handler reiserfs_posix_acl_default_handler = { |
524 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 524 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
525 | .flags = ACL_TYPE_DEFAULT, | 525 | .flags = ACL_TYPE_DEFAULT, |
526 | .get = posix_acl_get, | 526 | .get = posix_acl_get, |
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 7271a477c041..237c6928d3c6 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
@@ -111,7 +111,7 @@ void reiserfs_security_free(struct reiserfs_security_handle *sec) | |||
111 | sec->value = NULL; | 111 | sec->value = NULL; |
112 | } | 112 | } |
113 | 113 | ||
114 | struct xattr_handler reiserfs_xattr_security_handler = { | 114 | const struct xattr_handler reiserfs_xattr_security_handler = { |
115 | .prefix = XATTR_SECURITY_PREFIX, | 115 | .prefix = XATTR_SECURITY_PREFIX, |
116 | .get = security_get, | 116 | .get = security_get, |
117 | .set = security_set, | 117 | .set = security_set, |
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index 5b08aaca3daf..9883736ce3ec 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c | |||
@@ -48,7 +48,7 @@ static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size, | |||
48 | return len; | 48 | return len; |
49 | } | 49 | } |
50 | 50 | ||
51 | struct xattr_handler reiserfs_xattr_trusted_handler = { | 51 | const struct xattr_handler reiserfs_xattr_trusted_handler = { |
52 | .prefix = XATTR_TRUSTED_PREFIX, | 52 | .prefix = XATTR_TRUSTED_PREFIX, |
53 | .get = trusted_get, | 53 | .get = trusted_get, |
54 | .set = trusted_set, | 54 | .set = trusted_set, |
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index 75d59c49b911..45ae1a00013a 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c | |||
@@ -44,7 +44,7 @@ static size_t user_list(struct dentry *dentry, char *list, size_t list_size, | |||
44 | return len; | 44 | return len; |
45 | } | 45 | } |
46 | 46 | ||
47 | struct xattr_handler reiserfs_xattr_user_handler = { | 47 | const struct xattr_handler reiserfs_xattr_user_handler = { |
48 | .prefix = XATTR_USER_PREFIX, | 48 | .prefix = XATTR_USER_PREFIX, |
49 | .get = user_get, | 49 | .get = user_get, |
50 | .set = user_set, | 50 | .set = user_set, |
diff --git a/fs/statfs.c b/fs/statfs.c new file mode 100644 index 000000000000..4ef021f3b612 --- /dev/null +++ b/fs/statfs.c | |||
@@ -0,0 +1,196 @@ | |||
1 | #include <linux/syscalls.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/fs.h> | ||
4 | #include <linux/file.h> | ||
5 | #include <linux/namei.h> | ||
6 | #include <linux/statfs.h> | ||
7 | #include <linux/security.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | |||
10 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
11 | { | ||
12 | int retval = -ENODEV; | ||
13 | |||
14 | if (dentry) { | ||
15 | retval = -ENOSYS; | ||
16 | if (dentry->d_sb->s_op->statfs) { | ||
17 | memset(buf, 0, sizeof(*buf)); | ||
18 | retval = security_sb_statfs(dentry); | ||
19 | if (retval) | ||
20 | return retval; | ||
21 | retval = dentry->d_sb->s_op->statfs(dentry, buf); | ||
22 | if (retval == 0 && buf->f_frsize == 0) | ||
23 | buf->f_frsize = buf->f_bsize; | ||
24 | } | ||
25 | } | ||
26 | return retval; | ||
27 | } | ||
28 | |||
29 | EXPORT_SYMBOL(vfs_statfs); | ||
30 | |||
31 | static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) | ||
32 | { | ||
33 | struct kstatfs st; | ||
34 | int retval; | ||
35 | |||
36 | retval = vfs_statfs(dentry, &st); | ||
37 | if (retval) | ||
38 | return retval; | ||
39 | |||
40 | if (sizeof(*buf) == sizeof(st)) | ||
41 | memcpy(buf, &st, sizeof(st)); | ||
42 | else { | ||
43 | if (sizeof buf->f_blocks == 4) { | ||
44 | if ((st.f_blocks | st.f_bfree | st.f_bavail | | ||
45 | st.f_bsize | st.f_frsize) & | ||
46 | 0xffffffff00000000ULL) | ||
47 | return -EOVERFLOW; | ||
48 | /* | ||
49 | * f_files and f_ffree may be -1; it's okay to stuff | ||
50 | * that into 32 bits | ||
51 | */ | ||
52 | if (st.f_files != -1 && | ||
53 | (st.f_files & 0xffffffff00000000ULL)) | ||
54 | return -EOVERFLOW; | ||
55 | if (st.f_ffree != -1 && | ||
56 | (st.f_ffree & 0xffffffff00000000ULL)) | ||
57 | return -EOVERFLOW; | ||
58 | } | ||
59 | |||
60 | buf->f_type = st.f_type; | ||
61 | buf->f_bsize = st.f_bsize; | ||
62 | buf->f_blocks = st.f_blocks; | ||
63 | buf->f_bfree = st.f_bfree; | ||
64 | buf->f_bavail = st.f_bavail; | ||
65 | buf->f_files = st.f_files; | ||
66 | buf->f_ffree = st.f_ffree; | ||
67 | buf->f_fsid = st.f_fsid; | ||
68 | buf->f_namelen = st.f_namelen; | ||
69 | buf->f_frsize = st.f_frsize; | ||
70 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
71 | } | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) | ||
76 | { | ||
77 | struct kstatfs st; | ||
78 | int retval; | ||
79 | |||
80 | retval = vfs_statfs(dentry, &st); | ||
81 | if (retval) | ||
82 | return retval; | ||
83 | |||
84 | if (sizeof(*buf) == sizeof(st)) | ||
85 | memcpy(buf, &st, sizeof(st)); | ||
86 | else { | ||
87 | buf->f_type = st.f_type; | ||
88 | buf->f_bsize = st.f_bsize; | ||
89 | buf->f_blocks = st.f_blocks; | ||
90 | buf->f_bfree = st.f_bfree; | ||
91 | buf->f_bavail = st.f_bavail; | ||
92 | buf->f_files = st.f_files; | ||
93 | buf->f_ffree = st.f_ffree; | ||
94 | buf->f_fsid = st.f_fsid; | ||
95 | buf->f_namelen = st.f_namelen; | ||
96 | buf->f_frsize = st.f_frsize; | ||
97 | memset(buf->f_spare, 0, sizeof(buf->f_spare)); | ||
98 | } | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) | ||
103 | { | ||
104 | struct path path; | ||
105 | int error; | ||
106 | |||
107 | error = user_path(pathname, &path); | ||
108 | if (!error) { | ||
109 | struct statfs tmp; | ||
110 | error = vfs_statfs_native(path.dentry, &tmp); | ||
111 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
112 | error = -EFAULT; | ||
113 | path_put(&path); | ||
114 | } | ||
115 | return error; | ||
116 | } | ||
117 | |||
118 | SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) | ||
119 | { | ||
120 | struct path path; | ||
121 | long error; | ||
122 | |||
123 | if (sz != sizeof(*buf)) | ||
124 | return -EINVAL; | ||
125 | error = user_path(pathname, &path); | ||
126 | if (!error) { | ||
127 | struct statfs64 tmp; | ||
128 | error = vfs_statfs64(path.dentry, &tmp); | ||
129 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
130 | error = -EFAULT; | ||
131 | path_put(&path); | ||
132 | } | ||
133 | return error; | ||
134 | } | ||
135 | |||
136 | SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) | ||
137 | { | ||
138 | struct file *file; | ||
139 | struct statfs tmp; | ||
140 | int error; | ||
141 | |||
142 | error = -EBADF; | ||
143 | file = fget(fd); | ||
144 | if (!file) | ||
145 | goto out; | ||
146 | error = vfs_statfs_native(file->f_path.dentry, &tmp); | ||
147 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
148 | error = -EFAULT; | ||
149 | fput(file); | ||
150 | out: | ||
151 | return error; | ||
152 | } | ||
153 | |||
154 | SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) | ||
155 | { | ||
156 | struct file *file; | ||
157 | struct statfs64 tmp; | ||
158 | int error; | ||
159 | |||
160 | if (sz != sizeof(*buf)) | ||
161 | return -EINVAL; | ||
162 | |||
163 | error = -EBADF; | ||
164 | file = fget(fd); | ||
165 | if (!file) | ||
166 | goto out; | ||
167 | error = vfs_statfs64(file->f_path.dentry, &tmp); | ||
168 | if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) | ||
169 | error = -EFAULT; | ||
170 | fput(file); | ||
171 | out: | ||
172 | return error; | ||
173 | } | ||
174 | |||
175 | SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) | ||
176 | { | ||
177 | struct super_block *s; | ||
178 | struct ustat tmp; | ||
179 | struct kstatfs sbuf; | ||
180 | int err; | ||
181 | |||
182 | s = user_get_super(new_decode_dev(dev)); | ||
183 | if (!s) | ||
184 | return -EINVAL; | ||
185 | |||
186 | err = vfs_statfs(s->s_root, &sbuf); | ||
187 | drop_super(s); | ||
188 | if (err) | ||
189 | return err; | ||
190 | |||
191 | memset(&tmp,0,sizeof(struct ustat)); | ||
192 | tmp.f_tfree = sbuf.f_bfree; | ||
193 | tmp.f_tinode = sbuf.f_ffree; | ||
194 | |||
195 | return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; | ||
196 | } | ||
diff --git a/fs/super.c b/fs/super.c index 1527e6a0ee35..69688b15f1fa 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -22,23 +22,15 @@ | |||
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/init.h> | ||
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/acct.h> | 25 | #include <linux/acct.h> |
28 | #include <linux/blkdev.h> | 26 | #include <linux/blkdev.h> |
29 | #include <linux/quotaops.h> | 27 | #include <linux/quotaops.h> |
30 | #include <linux/namei.h> | ||
31 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
32 | #include <linux/security.h> | 29 | #include <linux/security.h> |
33 | #include <linux/syscalls.h> | ||
34 | #include <linux/vfs.h> | ||
35 | #include <linux/writeback.h> /* for the emergency remount stuff */ | 30 | #include <linux/writeback.h> /* for the emergency remount stuff */ |
36 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
37 | #include <linux/kobject.h> | ||
38 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
39 | #include <linux/file.h> | ||
40 | #include <linux/backing-dev.h> | 33 | #include <linux/backing-dev.h> |
41 | #include <asm/uaccess.h> | ||
42 | #include "internal.h" | 34 | #include "internal.h" |
43 | 35 | ||
44 | 36 | ||
@@ -93,9 +85,10 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
93 | * subclass. | 85 | * subclass. |
94 | */ | 86 | */ |
95 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | 87 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); |
96 | s->s_count = S_BIAS; | 88 | s->s_count = 1; |
97 | atomic_set(&s->s_active, 1); | 89 | atomic_set(&s->s_active, 1); |
98 | mutex_init(&s->s_vfs_rename_mutex); | 90 | mutex_init(&s->s_vfs_rename_mutex); |
91 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); | ||
99 | mutex_init(&s->s_dquot.dqio_mutex); | 92 | mutex_init(&s->s_dquot.dqio_mutex); |
100 | mutex_init(&s->s_dquot.dqonoff_mutex); | 93 | mutex_init(&s->s_dquot.dqonoff_mutex); |
101 | init_rwsem(&s->s_dquot.dqptr_sem); | 94 | init_rwsem(&s->s_dquot.dqptr_sem); |
@@ -127,39 +120,14 @@ static inline void destroy_super(struct super_block *s) | |||
127 | /* Superblock refcounting */ | 120 | /* Superblock refcounting */ |
128 | 121 | ||
129 | /* | 122 | /* |
130 | * Drop a superblock's refcount. Returns non-zero if the superblock was | 123 | * Drop a superblock's refcount. The caller must hold sb_lock. |
131 | * destroyed. The caller must hold sb_lock. | ||
132 | */ | 124 | */ |
133 | static int __put_super(struct super_block *sb) | 125 | void __put_super(struct super_block *sb) |
134 | { | 126 | { |
135 | int ret = 0; | ||
136 | |||
137 | if (!--sb->s_count) { | 127 | if (!--sb->s_count) { |
128 | list_del_init(&sb->s_list); | ||
138 | destroy_super(sb); | 129 | destroy_super(sb); |
139 | ret = 1; | ||
140 | } | 130 | } |
141 | return ret; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Drop a superblock's refcount. | ||
146 | * Returns non-zero if the superblock is about to be destroyed and | ||
147 | * at least is already removed from super_blocks list, so if we are | ||
148 | * making a loop through super blocks then we need to restart. | ||
149 | * The caller must hold sb_lock. | ||
150 | */ | ||
151 | int __put_super_and_need_restart(struct super_block *sb) | ||
152 | { | ||
153 | /* check for race with generic_shutdown_super() */ | ||
154 | if (list_empty(&sb->s_list)) { | ||
155 | /* super block is removed, need to restart... */ | ||
156 | __put_super(sb); | ||
157 | return 1; | ||
158 | } | ||
159 | /* can't be the last, since s_list is still in use */ | ||
160 | sb->s_count--; | ||
161 | BUG_ON(sb->s_count == 0); | ||
162 | return 0; | ||
163 | } | 131 | } |
164 | 132 | ||
165 | /** | 133 | /** |
@@ -178,57 +146,48 @@ void put_super(struct super_block *sb) | |||
178 | 146 | ||
179 | 147 | ||
180 | /** | 148 | /** |
181 | * deactivate_super - drop an active reference to superblock | 149 | * deactivate_locked_super - drop an active reference to superblock |
182 | * @s: superblock to deactivate | 150 | * @s: superblock to deactivate |
183 | * | 151 | * |
184 | * Drops an active reference to superblock, acquiring a temprory one if | 152 | * Drops an active reference to superblock, converting it into a temprory |
185 | * there is no active references left. In that case we lock superblock, | 153 | * one if there is no other active references left. In that case we |
186 | * tell fs driver to shut it down and drop the temporary reference we | 154 | * tell fs driver to shut it down and drop the temporary reference we |
187 | * had just acquired. | 155 | * had just acquired. |
156 | * | ||
157 | * Caller holds exclusive lock on superblock; that lock is released. | ||
188 | */ | 158 | */ |
189 | void deactivate_super(struct super_block *s) | 159 | void deactivate_locked_super(struct super_block *s) |
190 | { | 160 | { |
191 | struct file_system_type *fs = s->s_type; | 161 | struct file_system_type *fs = s->s_type; |
192 | if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { | 162 | if (atomic_dec_and_test(&s->s_active)) { |
193 | s->s_count -= S_BIAS-1; | ||
194 | spin_unlock(&sb_lock); | ||
195 | vfs_dq_off(s, 0); | 163 | vfs_dq_off(s, 0); |
196 | down_write(&s->s_umount); | ||
197 | fs->kill_sb(s); | 164 | fs->kill_sb(s); |
198 | put_filesystem(fs); | 165 | put_filesystem(fs); |
199 | put_super(s); | 166 | put_super(s); |
167 | } else { | ||
168 | up_write(&s->s_umount); | ||
200 | } | 169 | } |
201 | } | 170 | } |
202 | 171 | ||
203 | EXPORT_SYMBOL(deactivate_super); | 172 | EXPORT_SYMBOL(deactivate_locked_super); |
204 | 173 | ||
205 | /** | 174 | /** |
206 | * deactivate_locked_super - drop an active reference to superblock | 175 | * deactivate_super - drop an active reference to superblock |
207 | * @s: superblock to deactivate | 176 | * @s: superblock to deactivate |
208 | * | 177 | * |
209 | * Equivalent of up_write(&s->s_umount); deactivate_super(s);, except that | 178 | * Variant of deactivate_locked_super(), except that superblock is *not* |
210 | * it does not unlock it until it's all over. As the result, it's safe to | 179 | * locked by caller. If we are going to drop the final active reference, |
211 | * use to dispose of new superblock on ->get_sb() failure exits - nobody | 180 | * lock will be acquired prior to that. |
212 | * will see the sucker until it's all over. Equivalent using up_write + | ||
213 | * deactivate_super is safe for that purpose only if superblock is either | ||
214 | * safe to use or has NULL ->s_root when we unlock. | ||
215 | */ | 181 | */ |
216 | void deactivate_locked_super(struct super_block *s) | 182 | void deactivate_super(struct super_block *s) |
217 | { | 183 | { |
218 | struct file_system_type *fs = s->s_type; | 184 | if (!atomic_add_unless(&s->s_active, -1, 1)) { |
219 | if (atomic_dec_and_lock(&s->s_active, &sb_lock)) { | 185 | down_write(&s->s_umount); |
220 | s->s_count -= S_BIAS-1; | 186 | deactivate_locked_super(s); |
221 | spin_unlock(&sb_lock); | ||
222 | vfs_dq_off(s, 0); | ||
223 | fs->kill_sb(s); | ||
224 | put_filesystem(fs); | ||
225 | put_super(s); | ||
226 | } else { | ||
227 | up_write(&s->s_umount); | ||
228 | } | 187 | } |
229 | } | 188 | } |
230 | 189 | ||
231 | EXPORT_SYMBOL(deactivate_locked_super); | 190 | EXPORT_SYMBOL(deactivate_super); |
232 | 191 | ||
233 | /** | 192 | /** |
234 | * grab_super - acquire an active reference | 193 | * grab_super - acquire an active reference |
@@ -243,22 +202,17 @@ EXPORT_SYMBOL(deactivate_locked_super); | |||
243 | */ | 202 | */ |
244 | static int grab_super(struct super_block *s) __releases(sb_lock) | 203 | static int grab_super(struct super_block *s) __releases(sb_lock) |
245 | { | 204 | { |
205 | if (atomic_inc_not_zero(&s->s_active)) { | ||
206 | spin_unlock(&sb_lock); | ||
207 | return 1; | ||
208 | } | ||
209 | /* it's going away */ | ||
246 | s->s_count++; | 210 | s->s_count++; |
247 | spin_unlock(&sb_lock); | 211 | spin_unlock(&sb_lock); |
212 | /* wait for it to die */ | ||
248 | down_write(&s->s_umount); | 213 | down_write(&s->s_umount); |
249 | if (s->s_root) { | ||
250 | spin_lock(&sb_lock); | ||
251 | if (s->s_count > S_BIAS) { | ||
252 | atomic_inc(&s->s_active); | ||
253 | s->s_count--; | ||
254 | spin_unlock(&sb_lock); | ||
255 | return 1; | ||
256 | } | ||
257 | spin_unlock(&sb_lock); | ||
258 | } | ||
259 | up_write(&s->s_umount); | 214 | up_write(&s->s_umount); |
260 | put_super(s); | 215 | put_super(s); |
261 | yield(); | ||
262 | return 0; | 216 | return 0; |
263 | } | 217 | } |
264 | 218 | ||
@@ -321,8 +275,7 @@ void generic_shutdown_super(struct super_block *sb) | |||
321 | } | 275 | } |
322 | spin_lock(&sb_lock); | 276 | spin_lock(&sb_lock); |
323 | /* should be initialized for __put_super_and_need_restart() */ | 277 | /* should be initialized for __put_super_and_need_restart() */ |
324 | list_del_init(&sb->s_list); | 278 | list_del_init(&sb->s_instances); |
325 | list_del(&sb->s_instances); | ||
326 | spin_unlock(&sb_lock); | 279 | spin_unlock(&sb_lock); |
327 | up_write(&sb->s_umount); | 280 | up_write(&sb->s_umount); |
328 | } | 281 | } |
@@ -357,6 +310,7 @@ retry: | |||
357 | up_write(&s->s_umount); | 310 | up_write(&s->s_umount); |
358 | destroy_super(s); | 311 | destroy_super(s); |
359 | } | 312 | } |
313 | down_write(&old->s_umount); | ||
360 | return old; | 314 | return old; |
361 | } | 315 | } |
362 | } | 316 | } |
@@ -408,11 +362,12 @@ EXPORT_SYMBOL(drop_super); | |||
408 | */ | 362 | */ |
409 | void sync_supers(void) | 363 | void sync_supers(void) |
410 | { | 364 | { |
411 | struct super_block *sb; | 365 | struct super_block *sb, *n; |
412 | 366 | ||
413 | spin_lock(&sb_lock); | 367 | spin_lock(&sb_lock); |
414 | restart: | 368 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
415 | list_for_each_entry(sb, &super_blocks, s_list) { | 369 | if (list_empty(&sb->s_instances)) |
370 | continue; | ||
416 | if (sb->s_op->write_super && sb->s_dirt) { | 371 | if (sb->s_op->write_super && sb->s_dirt) { |
417 | sb->s_count++; | 372 | sb->s_count++; |
418 | spin_unlock(&sb_lock); | 373 | spin_unlock(&sb_lock); |
@@ -423,14 +378,43 @@ restart: | |||
423 | up_read(&sb->s_umount); | 378 | up_read(&sb->s_umount); |
424 | 379 | ||
425 | spin_lock(&sb_lock); | 380 | spin_lock(&sb_lock); |
426 | if (__put_super_and_need_restart(sb)) | 381 | __put_super(sb); |
427 | goto restart; | ||
428 | } | 382 | } |
429 | } | 383 | } |
430 | spin_unlock(&sb_lock); | 384 | spin_unlock(&sb_lock); |
431 | } | 385 | } |
432 | 386 | ||
433 | /** | 387 | /** |
388 | * iterate_supers - call function for all active superblocks | ||
389 | * @f: function to call | ||
390 | * @arg: argument to pass to it | ||
391 | * | ||
392 | * Scans the superblock list and calls given function, passing it | ||
393 | * locked superblock and given argument. | ||
394 | */ | ||
395 | void iterate_supers(void (*f)(struct super_block *, void *), void *arg) | ||
396 | { | ||
397 | struct super_block *sb, *n; | ||
398 | |||
399 | spin_lock(&sb_lock); | ||
400 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { | ||
401 | if (list_empty(&sb->s_instances)) | ||
402 | continue; | ||
403 | sb->s_count++; | ||
404 | spin_unlock(&sb_lock); | ||
405 | |||
406 | down_read(&sb->s_umount); | ||
407 | if (sb->s_root) | ||
408 | f(sb, arg); | ||
409 | up_read(&sb->s_umount); | ||
410 | |||
411 | spin_lock(&sb_lock); | ||
412 | __put_super(sb); | ||
413 | } | ||
414 | spin_unlock(&sb_lock); | ||
415 | } | ||
416 | |||
417 | /** | ||
434 | * get_super - get the superblock of a device | 418 | * get_super - get the superblock of a device |
435 | * @bdev: device to get the superblock for | 419 | * @bdev: device to get the superblock for |
436 | * | 420 | * |
@@ -438,7 +422,7 @@ restart: | |||
438 | * mounted on the device given. %NULL is returned if no match is found. | 422 | * mounted on the device given. %NULL is returned if no match is found. |
439 | */ | 423 | */ |
440 | 424 | ||
441 | struct super_block * get_super(struct block_device *bdev) | 425 | struct super_block *get_super(struct block_device *bdev) |
442 | { | 426 | { |
443 | struct super_block *sb; | 427 | struct super_block *sb; |
444 | 428 | ||
@@ -448,17 +432,20 @@ struct super_block * get_super(struct block_device *bdev) | |||
448 | spin_lock(&sb_lock); | 432 | spin_lock(&sb_lock); |
449 | rescan: | 433 | rescan: |
450 | list_for_each_entry(sb, &super_blocks, s_list) { | 434 | list_for_each_entry(sb, &super_blocks, s_list) { |
435 | if (list_empty(&sb->s_instances)) | ||
436 | continue; | ||
451 | if (sb->s_bdev == bdev) { | 437 | if (sb->s_bdev == bdev) { |
452 | sb->s_count++; | 438 | sb->s_count++; |
453 | spin_unlock(&sb_lock); | 439 | spin_unlock(&sb_lock); |
454 | down_read(&sb->s_umount); | 440 | down_read(&sb->s_umount); |
441 | /* still alive? */ | ||
455 | if (sb->s_root) | 442 | if (sb->s_root) |
456 | return sb; | 443 | return sb; |
457 | up_read(&sb->s_umount); | 444 | up_read(&sb->s_umount); |
458 | /* restart only when sb is no longer on the list */ | 445 | /* nope, got unmounted */ |
459 | spin_lock(&sb_lock); | 446 | spin_lock(&sb_lock); |
460 | if (__put_super_and_need_restart(sb)) | 447 | __put_super(sb); |
461 | goto rescan; | 448 | goto rescan; |
462 | } | 449 | } |
463 | } | 450 | } |
464 | spin_unlock(&sb_lock); | 451 | spin_unlock(&sb_lock); |
@@ -473,7 +460,7 @@ EXPORT_SYMBOL(get_super); | |||
473 | * | 460 | * |
474 | * Scans the superblock list and finds the superblock of the file system | 461 | * Scans the superblock list and finds the superblock of the file system |
475 | * mounted on the device given. Returns the superblock with an active | 462 | * mounted on the device given. Returns the superblock with an active |
476 | * reference and s_umount held exclusively or %NULL if none was found. | 463 | * reference or %NULL if none was found. |
477 | */ | 464 | */ |
478 | struct super_block *get_active_super(struct block_device *bdev) | 465 | struct super_block *get_active_super(struct block_device *bdev) |
479 | { | 466 | { |
@@ -482,81 +469,49 @@ struct super_block *get_active_super(struct block_device *bdev) | |||
482 | if (!bdev) | 469 | if (!bdev) |
483 | return NULL; | 470 | return NULL; |
484 | 471 | ||
472 | restart: | ||
485 | spin_lock(&sb_lock); | 473 | spin_lock(&sb_lock); |
486 | list_for_each_entry(sb, &super_blocks, s_list) { | 474 | list_for_each_entry(sb, &super_blocks, s_list) { |
487 | if (sb->s_bdev != bdev) | 475 | if (list_empty(&sb->s_instances)) |
488 | continue; | 476 | continue; |
489 | 477 | if (sb->s_bdev == bdev) { | |
490 | sb->s_count++; | 478 | if (grab_super(sb)) /* drops sb_lock */ |
491 | spin_unlock(&sb_lock); | ||
492 | down_write(&sb->s_umount); | ||
493 | if (sb->s_root) { | ||
494 | spin_lock(&sb_lock); | ||
495 | if (sb->s_count > S_BIAS) { | ||
496 | atomic_inc(&sb->s_active); | ||
497 | sb->s_count--; | ||
498 | spin_unlock(&sb_lock); | ||
499 | return sb; | 479 | return sb; |
500 | } | 480 | else |
501 | spin_unlock(&sb_lock); | 481 | goto restart; |
502 | } | 482 | } |
503 | up_write(&sb->s_umount); | ||
504 | put_super(sb); | ||
505 | yield(); | ||
506 | spin_lock(&sb_lock); | ||
507 | } | 483 | } |
508 | spin_unlock(&sb_lock); | 484 | spin_unlock(&sb_lock); |
509 | return NULL; | 485 | return NULL; |
510 | } | 486 | } |
511 | 487 | ||
512 | struct super_block * user_get_super(dev_t dev) | 488 | struct super_block *user_get_super(dev_t dev) |
513 | { | 489 | { |
514 | struct super_block *sb; | 490 | struct super_block *sb; |
515 | 491 | ||
516 | spin_lock(&sb_lock); | 492 | spin_lock(&sb_lock); |
517 | rescan: | 493 | rescan: |
518 | list_for_each_entry(sb, &super_blocks, s_list) { | 494 | list_for_each_entry(sb, &super_blocks, s_list) { |
495 | if (list_empty(&sb->s_instances)) | ||
496 | continue; | ||
519 | if (sb->s_dev == dev) { | 497 | if (sb->s_dev == dev) { |
520 | sb->s_count++; | 498 | sb->s_count++; |
521 | spin_unlock(&sb_lock); | 499 | spin_unlock(&sb_lock); |
522 | down_read(&sb->s_umount); | 500 | down_read(&sb->s_umount); |
501 | /* still alive? */ | ||
523 | if (sb->s_root) | 502 | if (sb->s_root) |
524 | return sb; | 503 | return sb; |
525 | up_read(&sb->s_umount); | 504 | up_read(&sb->s_umount); |
526 | /* restart only when sb is no longer on the list */ | 505 | /* nope, got unmounted */ |
527 | spin_lock(&sb_lock); | 506 | spin_lock(&sb_lock); |
528 | if (__put_super_and_need_restart(sb)) | 507 | __put_super(sb); |
529 | goto rescan; | 508 | goto rescan; |
530 | } | 509 | } |
531 | } | 510 | } |
532 | spin_unlock(&sb_lock); | 511 | spin_unlock(&sb_lock); |
533 | return NULL; | 512 | return NULL; |
534 | } | 513 | } |
535 | 514 | ||
536 | SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) | ||
537 | { | ||
538 | struct super_block *s; | ||
539 | struct ustat tmp; | ||
540 | struct kstatfs sbuf; | ||
541 | int err = -EINVAL; | ||
542 | |||
543 | s = user_get_super(new_decode_dev(dev)); | ||
544 | if (s == NULL) | ||
545 | goto out; | ||
546 | err = vfs_statfs(s->s_root, &sbuf); | ||
547 | drop_super(s); | ||
548 | if (err) | ||
549 | goto out; | ||
550 | |||
551 | memset(&tmp,0,sizeof(struct ustat)); | ||
552 | tmp.f_tfree = sbuf.f_bfree; | ||
553 | tmp.f_tinode = sbuf.f_ffree; | ||
554 | |||
555 | err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0; | ||
556 | out: | ||
557 | return err; | ||
558 | } | ||
559 | |||
560 | /** | 515 | /** |
561 | * do_remount_sb - asks filesystem to change mount options. | 516 | * do_remount_sb - asks filesystem to change mount options. |
562 | * @sb: superblock in question | 517 | * @sb: superblock in question |
@@ -622,24 +577,24 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
622 | 577 | ||
623 | static void do_emergency_remount(struct work_struct *work) | 578 | static void do_emergency_remount(struct work_struct *work) |
624 | { | 579 | { |
625 | struct super_block *sb; | 580 | struct super_block *sb, *n; |
626 | 581 | ||
627 | spin_lock(&sb_lock); | 582 | spin_lock(&sb_lock); |
628 | list_for_each_entry(sb, &super_blocks, s_list) { | 583 | list_for_each_entry_safe(sb, n, &super_blocks, s_list) { |
584 | if (list_empty(&sb->s_instances)) | ||
585 | continue; | ||
629 | sb->s_count++; | 586 | sb->s_count++; |
630 | spin_unlock(&sb_lock); | 587 | spin_unlock(&sb_lock); |
631 | down_write(&sb->s_umount); | 588 | down_write(&sb->s_umount); |
632 | if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) { | 589 | if (sb->s_root && sb->s_bdev && !(sb->s_flags & MS_RDONLY)) { |
633 | /* | 590 | /* |
634 | * ->remount_fs needs lock_kernel(). | ||
635 | * | ||
636 | * What lock protects sb->s_flags?? | 591 | * What lock protects sb->s_flags?? |
637 | */ | 592 | */ |
638 | do_remount_sb(sb, MS_RDONLY, NULL, 1); | 593 | do_remount_sb(sb, MS_RDONLY, NULL, 1); |
639 | } | 594 | } |
640 | up_write(&sb->s_umount); | 595 | up_write(&sb->s_umount); |
641 | put_super(sb); | ||
642 | spin_lock(&sb_lock); | 596 | spin_lock(&sb_lock); |
597 | __put_super(sb); | ||
643 | } | 598 | } |
644 | spin_unlock(&sb_lock); | 599 | spin_unlock(&sb_lock); |
645 | kfree(work); | 600 | kfree(work); |
@@ -990,6 +945,96 @@ out: | |||
990 | 945 | ||
991 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 946 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
992 | 947 | ||
948 | /** | ||
949 | * freeze_super -- lock the filesystem and force it into a consistent state | ||
950 | * @super: the super to lock | ||
951 | * | ||
952 | * Syncs the super to make sure the filesystem is consistent and calls the fs's | ||
953 | * freeze_fs. Subsequent calls to this without first thawing the fs will return | ||
954 | * -EBUSY. | ||
955 | */ | ||
956 | int freeze_super(struct super_block *sb) | ||
957 | { | ||
958 | int ret; | ||
959 | |||
960 | atomic_inc(&sb->s_active); | ||
961 | down_write(&sb->s_umount); | ||
962 | if (sb->s_frozen) { | ||
963 | deactivate_locked_super(sb); | ||
964 | return -EBUSY; | ||
965 | } | ||
966 | |||
967 | if (sb->s_flags & MS_RDONLY) { | ||
968 | sb->s_frozen = SB_FREEZE_TRANS; | ||
969 | smp_wmb(); | ||
970 | up_write(&sb->s_umount); | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | sb->s_frozen = SB_FREEZE_WRITE; | ||
975 | smp_wmb(); | ||
976 | |||
977 | sync_filesystem(sb); | ||
978 | |||
979 | sb->s_frozen = SB_FREEZE_TRANS; | ||
980 | smp_wmb(); | ||
981 | |||
982 | sync_blockdev(sb->s_bdev); | ||
983 | if (sb->s_op->freeze_fs) { | ||
984 | ret = sb->s_op->freeze_fs(sb); | ||
985 | if (ret) { | ||
986 | printk(KERN_ERR | ||
987 | "VFS:Filesystem freeze failed\n"); | ||
988 | sb->s_frozen = SB_UNFROZEN; | ||
989 | deactivate_locked_super(sb); | ||
990 | return ret; | ||
991 | } | ||
992 | } | ||
993 | up_write(&sb->s_umount); | ||
994 | return 0; | ||
995 | } | ||
996 | EXPORT_SYMBOL(freeze_super); | ||
997 | |||
998 | /** | ||
999 | * thaw_super -- unlock filesystem | ||
1000 | * @sb: the super to thaw | ||
1001 | * | ||
1002 | * Unlocks the filesystem and marks it writeable again after freeze_super(). | ||
1003 | */ | ||
1004 | int thaw_super(struct super_block *sb) | ||
1005 | { | ||
1006 | int error; | ||
1007 | |||
1008 | down_write(&sb->s_umount); | ||
1009 | if (sb->s_frozen == SB_UNFROZEN) { | ||
1010 | up_write(&sb->s_umount); | ||
1011 | return -EINVAL; | ||
1012 | } | ||
1013 | |||
1014 | if (sb->s_flags & MS_RDONLY) | ||
1015 | goto out; | ||
1016 | |||
1017 | if (sb->s_op->unfreeze_fs) { | ||
1018 | error = sb->s_op->unfreeze_fs(sb); | ||
1019 | if (error) { | ||
1020 | printk(KERN_ERR | ||
1021 | "VFS:Filesystem thaw failed\n"); | ||
1022 | sb->s_frozen = SB_FREEZE_TRANS; | ||
1023 | up_write(&sb->s_umount); | ||
1024 | return error; | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | out: | ||
1029 | sb->s_frozen = SB_UNFROZEN; | ||
1030 | smp_wmb(); | ||
1031 | wake_up(&sb->s_wait_unfrozen); | ||
1032 | deactivate_locked_super(sb); | ||
1033 | |||
1034 | return 0; | ||
1035 | } | ||
1036 | EXPORT_SYMBOL(thaw_super); | ||
1037 | |||
993 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) | 1038 | static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype) |
994 | { | 1039 | { |
995 | int err; | 1040 | int err; |
@@ -77,50 +77,18 @@ int sync_filesystem(struct super_block *sb) | |||
77 | } | 77 | } |
78 | EXPORT_SYMBOL_GPL(sync_filesystem); | 78 | EXPORT_SYMBOL_GPL(sync_filesystem); |
79 | 79 | ||
80 | static void sync_one_sb(struct super_block *sb, void *arg) | ||
81 | { | ||
82 | if (!(sb->s_flags & MS_RDONLY) && sb->s_bdi) | ||
83 | __sync_filesystem(sb, *(int *)arg); | ||
84 | } | ||
80 | /* | 85 | /* |
81 | * Sync all the data for all the filesystems (called by sys_sync() and | 86 | * Sync all the data for all the filesystems (called by sys_sync() and |
82 | * emergency sync) | 87 | * emergency sync) |
83 | * | ||
84 | * This operation is careful to avoid the livelock which could easily happen | ||
85 | * if two or more filesystems are being continuously dirtied. s_need_sync | ||
86 | * is used only here. We set it against all filesystems and then clear it as | ||
87 | * we sync them. So redirtied filesystems are skipped. | ||
88 | * | ||
89 | * But if process A is currently running sync_filesystems and then process B | ||
90 | * calls sync_filesystems as well, process B will set all the s_need_sync | ||
91 | * flags again, which will cause process A to resync everything. Fix that with | ||
92 | * a local mutex. | ||
93 | */ | 88 | */ |
94 | static void sync_filesystems(int wait) | 89 | static void sync_filesystems(int wait) |
95 | { | 90 | { |
96 | struct super_block *sb; | 91 | iterate_supers(sync_one_sb, &wait); |
97 | static DEFINE_MUTEX(mutex); | ||
98 | |||
99 | mutex_lock(&mutex); /* Could be down_interruptible */ | ||
100 | spin_lock(&sb_lock); | ||
101 | list_for_each_entry(sb, &super_blocks, s_list) | ||
102 | sb->s_need_sync = 1; | ||
103 | |||
104 | restart: | ||
105 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
106 | if (!sb->s_need_sync) | ||
107 | continue; | ||
108 | sb->s_need_sync = 0; | ||
109 | sb->s_count++; | ||
110 | spin_unlock(&sb_lock); | ||
111 | |||
112 | down_read(&sb->s_umount); | ||
113 | if (!(sb->s_flags & MS_RDONLY) && sb->s_root && sb->s_bdi) | ||
114 | __sync_filesystem(sb, wait); | ||
115 | up_read(&sb->s_umount); | ||
116 | |||
117 | /* restart only when sb is no longer on the list */ | ||
118 | spin_lock(&sb_lock); | ||
119 | if (__put_super_and_need_restart(sb)) | ||
120 | goto restart; | ||
121 | } | ||
122 | spin_unlock(&sb_lock); | ||
123 | mutex_unlock(&mutex); | ||
124 | } | 92 | } |
125 | 93 | ||
126 | /* | 94 | /* |
@@ -190,7 +158,6 @@ EXPORT_SYMBOL(file_fsync); | |||
190 | /** | 158 | /** |
191 | * vfs_fsync_range - helper to sync a range of data & metadata to disk | 159 | * vfs_fsync_range - helper to sync a range of data & metadata to disk |
192 | * @file: file to sync | 160 | * @file: file to sync |
193 | * @dentry: dentry of @file | ||
194 | * @start: offset in bytes of the beginning of data range to sync | 161 | * @start: offset in bytes of the beginning of data range to sync |
195 | * @end: offset in bytes of the end of data range (inclusive) | 162 | * @end: offset in bytes of the end of data range (inclusive) |
196 | * @datasync: perform only datasync | 163 | * @datasync: perform only datasync |
@@ -198,32 +165,13 @@ EXPORT_SYMBOL(file_fsync); | |||
198 | * Write back data in range @start..@end and metadata for @file to disk. If | 165 | * Write back data in range @start..@end and metadata for @file to disk. If |
199 | * @datasync is set only metadata needed to access modified file data is | 166 | * @datasync is set only metadata needed to access modified file data is |
200 | * written. | 167 | * written. |
201 | * | ||
202 | * In case this function is called from nfsd @file may be %NULL and | ||
203 | * only @dentry is set. This can only happen when the filesystem | ||
204 | * implements the export_operations API. | ||
205 | */ | 168 | */ |
206 | int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, | 169 | int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) |
207 | loff_t end, int datasync) | ||
208 | { | 170 | { |
209 | const struct file_operations *fop; | 171 | struct address_space *mapping = file->f_mapping; |
210 | struct address_space *mapping; | ||
211 | int err, ret; | 172 | int err, ret; |
212 | 173 | ||
213 | /* | 174 | if (!file->f_op || !file->f_op->fsync) { |
214 | * Get mapping and operations from the file in case we have | ||
215 | * as file, or get the default values for them in case we | ||
216 | * don't have a struct file available. Damn nfsd.. | ||
217 | */ | ||
218 | if (file) { | ||
219 | mapping = file->f_mapping; | ||
220 | fop = file->f_op; | ||
221 | } else { | ||
222 | mapping = dentry->d_inode->i_mapping; | ||
223 | fop = dentry->d_inode->i_fop; | ||
224 | } | ||
225 | |||
226 | if (!fop || !fop->fsync) { | ||
227 | ret = -EINVAL; | 175 | ret = -EINVAL; |
228 | goto out; | 176 | goto out; |
229 | } | 177 | } |
@@ -235,7 +183,7 @@ int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, | |||
235 | * livelocks in fsync_buffers_list(). | 183 | * livelocks in fsync_buffers_list(). |
236 | */ | 184 | */ |
237 | mutex_lock(&mapping->host->i_mutex); | 185 | mutex_lock(&mapping->host->i_mutex); |
238 | err = fop->fsync(file, dentry, datasync); | 186 | err = file->f_op->fsync(file, file->f_path.dentry, datasync); |
239 | if (!ret) | 187 | if (!ret) |
240 | ret = err; | 188 | ret = err; |
241 | mutex_unlock(&mapping->host->i_mutex); | 189 | mutex_unlock(&mapping->host->i_mutex); |
@@ -248,19 +196,14 @@ EXPORT_SYMBOL(vfs_fsync_range); | |||
248 | /** | 196 | /** |
249 | * vfs_fsync - perform a fsync or fdatasync on a file | 197 | * vfs_fsync - perform a fsync or fdatasync on a file |
250 | * @file: file to sync | 198 | * @file: file to sync |
251 | * @dentry: dentry of @file | ||
252 | * @datasync: only perform a fdatasync operation | 199 | * @datasync: only perform a fdatasync operation |
253 | * | 200 | * |
254 | * Write back data and metadata for @file to disk. If @datasync is | 201 | * Write back data and metadata for @file to disk. If @datasync is |
255 | * set only metadata needed to access modified file data is written. | 202 | * set only metadata needed to access modified file data is written. |
256 | * | ||
257 | * In case this function is called from nfsd @file may be %NULL and | ||
258 | * only @dentry is set. This can only happen when the filesystem | ||
259 | * implements the export_operations API. | ||
260 | */ | 203 | */ |
261 | int vfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 204 | int vfs_fsync(struct file *file, int datasync) |
262 | { | 205 | { |
263 | return vfs_fsync_range(file, dentry, 0, LLONG_MAX, datasync); | 206 | return vfs_fsync_range(file, 0, LLONG_MAX, datasync); |
264 | } | 207 | } |
265 | EXPORT_SYMBOL(vfs_fsync); | 208 | EXPORT_SYMBOL(vfs_fsync); |
266 | 209 | ||
@@ -271,7 +214,7 @@ static int do_fsync(unsigned int fd, int datasync) | |||
271 | 214 | ||
272 | file = fget(fd); | 215 | file = fget(fd); |
273 | if (file) { | 216 | if (file) { |
274 | ret = vfs_fsync(file, file->f_path.dentry, datasync); | 217 | ret = vfs_fsync(file, datasync); |
275 | fput(file); | 218 | fput(file); |
276 | } | 219 | } |
277 | return ret; | 220 | return ret; |
@@ -299,8 +242,7 @@ int generic_write_sync(struct file *file, loff_t pos, loff_t count) | |||
299 | { | 242 | { |
300 | if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host)) | 243 | if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host)) |
301 | return 0; | 244 | return 0; |
302 | return vfs_fsync_range(file, file->f_path.dentry, pos, | 245 | return vfs_fsync_range(file, pos, pos + count - 1, |
303 | pos + count - 1, | ||
304 | (file->f_flags & __O_SYNC) ? 0 : 1); | 246 | (file->f_flags & __O_SYNC) ? 0 : 1); |
305 | } | 247 | } |
306 | EXPORT_SYMBOL(generic_write_sync); | 248 | EXPORT_SYMBOL(generic_write_sync); |
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index 241e9765cfad..bbd69bdb0fa8 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c | |||
@@ -159,15 +159,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
159 | *sbi->s_sb_fic_count = cpu_to_fs16(sbi, count); | 159 | *sbi->s_sb_fic_count = cpu_to_fs16(sbi, count); |
160 | fs16_add(sbi, sbi->s_sb_total_free_inodes, -1); | 160 | fs16_add(sbi, sbi->s_sb_total_free_inodes, -1); |
161 | dirty_sb(sb); | 161 | dirty_sb(sb); |
162 | 162 | inode_init_owner(inode, dir, mode); | |
163 | if (dir->i_mode & S_ISGID) { | ||
164 | inode->i_gid = dir->i_gid; | ||
165 | if (S_ISDIR(mode)) | ||
166 | mode |= S_ISGID; | ||
167 | } else | ||
168 | inode->i_gid = current_fsgid(); | ||
169 | |||
170 | inode->i_uid = current_fsuid(); | ||
171 | inode->i_ino = fs16_to_cpu(sbi, ino); | 163 | inode->i_ino = fs16_to_cpu(sbi, ino); |
172 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 164 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
173 | inode->i_blocks = 0; | 165 | inode->i_blocks = 0; |
@@ -176,7 +168,6 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
176 | insert_inode_hash(inode); | 168 | insert_inode_hash(inode); |
177 | mark_inode_dirty(inode); | 169 | mark_inode_dirty(inode); |
178 | 170 | ||
179 | inode->i_mode = mode; /* for sysv_write_inode() */ | ||
180 | sysv_write_inode(inode, 0); /* ensure inode not allocated again */ | 171 | sysv_write_inode(inode, 0); /* ensure inode not allocated again */ |
181 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ | 172 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ |
182 | /* That's it. */ | 173 | /* That's it. */ |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 401e503d44a1..87ebcce72213 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -104,14 +104,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, | |||
104 | */ | 104 | */ |
105 | inode->i_flags |= (S_NOCMTIME); | 105 | inode->i_flags |= (S_NOCMTIME); |
106 | 106 | ||
107 | inode->i_uid = current_fsuid(); | 107 | inode_init_owner(inode, dir, mode); |
108 | if (dir->i_mode & S_ISGID) { | ||
109 | inode->i_gid = dir->i_gid; | ||
110 | if (S_ISDIR(mode)) | ||
111 | mode |= S_ISGID; | ||
112 | } else | ||
113 | inode->i_gid = current_fsgid(); | ||
114 | inode->i_mode = mode; | ||
115 | inode->i_mtime = inode->i_atime = inode->i_ctime = | 108 | inode->i_mtime = inode->i_atime = inode->i_ctime = |
116 | ubifs_current_time(inode); | 109 | ubifs_current_time(inode); |
117 | inode->i_mapping->nrpages = 0; | 110 | inode->i_mapping->nrpages = 0; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index fb68c9cd0c3e..2b5586c7f02a 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -124,15 +124,8 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
124 | udf_updated_lvid(sb); | 124 | udf_updated_lvid(sb); |
125 | } | 125 | } |
126 | mutex_unlock(&sbi->s_alloc_mutex); | 126 | mutex_unlock(&sbi->s_alloc_mutex); |
127 | inode->i_mode = mode; | 127 | |
128 | inode->i_uid = current_fsuid(); | 128 | inode_init_owner(inode, dir, mode); |
129 | if (dir->i_mode & S_ISGID) { | ||
130 | inode->i_gid = dir->i_gid; | ||
131 | if (S_ISDIR(mode)) | ||
132 | mode |= S_ISGID; | ||
133 | } else { | ||
134 | inode->i_gid = current_fsgid(); | ||
135 | } | ||
136 | 129 | ||
137 | iinfo->i_location.logicalBlockNum = block; | 130 | iinfo->i_location.logicalBlockNum = block; |
138 | iinfo->i_location.partitionReferenceNum = | 131 | iinfo->i_location.partitionReferenceNum = |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 75816025f95f..585f733615dc 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -579,7 +579,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
579 | inode->i_data.a_ops = &udf_aops; | 579 | inode->i_data.a_ops = &udf_aops; |
580 | inode->i_op = &udf_file_inode_operations; | 580 | inode->i_op = &udf_file_inode_operations; |
581 | inode->i_fop = &udf_file_operations; | 581 | inode->i_fop = &udf_file_operations; |
582 | inode->i_mode = mode; | ||
583 | mark_inode_dirty(inode); | 582 | mark_inode_dirty(inode); |
584 | 583 | ||
585 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 584 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
@@ -627,7 +626,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
627 | goto out; | 626 | goto out; |
628 | 627 | ||
629 | iinfo = UDF_I(inode); | 628 | iinfo = UDF_I(inode); |
630 | inode->i_uid = current_fsuid(); | ||
631 | init_special_inode(inode, mode, rdev); | 629 | init_special_inode(inode, mode, rdev); |
632 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 630 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
633 | if (!fi) { | 631 | if (!fi) { |
@@ -674,7 +672,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
674 | goto out; | 672 | goto out; |
675 | 673 | ||
676 | err = -EIO; | 674 | err = -EIO; |
677 | inode = udf_new_inode(dir, S_IFDIR, &err); | 675 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); |
678 | if (!inode) | 676 | if (!inode) |
679 | goto out; | 677 | goto out; |
680 | 678 | ||
@@ -697,9 +695,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
697 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 695 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
698 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 696 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
699 | brelse(fibh.sbh); | 697 | brelse(fibh.sbh); |
700 | inode->i_mode = S_IFDIR | mode; | ||
701 | if (dir->i_mode & S_ISGID) | ||
702 | inode->i_mode |= S_ISGID; | ||
703 | mark_inode_dirty(inode); | 698 | mark_inode_dirty(inode); |
704 | 699 | ||
705 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 700 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
@@ -912,7 +907,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
912 | dquot_initialize(dir); | 907 | dquot_initialize(dir); |
913 | 908 | ||
914 | lock_kernel(); | 909 | lock_kernel(); |
915 | inode = udf_new_inode(dir, S_IFLNK, &err); | 910 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
916 | if (!inode) | 911 | if (!inode) |
917 | goto out; | 912 | goto out; |
918 | 913 | ||
@@ -923,7 +918,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
923 | } | 918 | } |
924 | 919 | ||
925 | iinfo = UDF_I(inode); | 920 | iinfo = UDF_I(inode); |
926 | inode->i_mode = S_IFLNK | S_IRWXUGO; | ||
927 | inode->i_data.a_ops = &udf_symlink_aops; | 921 | inode->i_data.a_ops = &udf_symlink_aops; |
928 | inode->i_op = &udf_symlink_inode_operations; | 922 | inode->i_op = &udf_symlink_inode_operations; |
929 | 923 | ||
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 230ecf608026..3a959d55084d 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -303,15 +303,7 @@ cg_found: | |||
303 | sb->s_dirt = 1; | 303 | sb->s_dirt = 1; |
304 | 304 | ||
305 | inode->i_ino = cg * uspi->s_ipg + bit; | 305 | inode->i_ino = cg * uspi->s_ipg + bit; |
306 | inode->i_mode = mode; | 306 | inode_init_owner(inode, dir, mode); |
307 | inode->i_uid = current_fsuid(); | ||
308 | if (dir->i_mode & S_ISGID) { | ||
309 | inode->i_gid = dir->i_gid; | ||
310 | if (S_ISDIR(mode)) | ||
311 | inode->i_mode |= S_ISGID; | ||
312 | } else | ||
313 | inode->i_gid = current_fsgid(); | ||
314 | |||
315 | inode->i_blocks = 0; | 307 | inode->i_blocks = 0; |
316 | inode->i_generation = 0; | 308 | inode->i_generation = 0; |
317 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 309 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
diff --git a/fs/xattr.c b/fs/xattr.c index 46f87e828b48..01bb8135e14a 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -590,10 +590,10 @@ strcmp_prefix(const char *a, const char *a_prefix) | |||
590 | /* | 590 | /* |
591 | * Find the xattr_handler with the matching prefix. | 591 | * Find the xattr_handler with the matching prefix. |
592 | */ | 592 | */ |
593 | static struct xattr_handler * | 593 | static const struct xattr_handler * |
594 | xattr_resolve_name(struct xattr_handler **handlers, const char **name) | 594 | xattr_resolve_name(const struct xattr_handler **handlers, const char **name) |
595 | { | 595 | { |
596 | struct xattr_handler *handler; | 596 | const struct xattr_handler *handler; |
597 | 597 | ||
598 | if (!*name) | 598 | if (!*name) |
599 | return NULL; | 599 | return NULL; |
@@ -614,7 +614,7 @@ xattr_resolve_name(struct xattr_handler **handlers, const char **name) | |||
614 | ssize_t | 614 | ssize_t |
615 | generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) | 615 | generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) |
616 | { | 616 | { |
617 | struct xattr_handler *handler; | 617 | const struct xattr_handler *handler; |
618 | 618 | ||
619 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 619 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
620 | if (!handler) | 620 | if (!handler) |
@@ -629,7 +629,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s | |||
629 | ssize_t | 629 | ssize_t |
630 | generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | 630 | generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) |
631 | { | 631 | { |
632 | struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr; | 632 | const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr; |
633 | unsigned int size = 0; | 633 | unsigned int size = 0; |
634 | 634 | ||
635 | if (!buffer) { | 635 | if (!buffer) { |
@@ -659,7 +659,7 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
659 | int | 659 | int |
660 | generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) | 660 | generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) |
661 | { | 661 | { |
662 | struct xattr_handler *handler; | 662 | const struct xattr_handler *handler; |
663 | 663 | ||
664 | if (size == 0) | 664 | if (size == 0) |
665 | value = ""; /* empty EA, do not remove */ | 665 | value = ""; /* empty EA, do not remove */ |
@@ -676,7 +676,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz | |||
676 | int | 676 | int |
677 | generic_removexattr(struct dentry *dentry, const char *name) | 677 | generic_removexattr(struct dentry *dentry, const char *name) |
678 | { | 678 | { |
679 | struct xattr_handler *handler; | 679 | const struct xattr_handler *handler; |
680 | 680 | ||
681 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 681 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
682 | if (!handler) | 682 | if (!handler) |
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index a7bc925c4d60..9f769b5b38fc 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c | |||
@@ -440,14 +440,14 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
440 | return error; | 440 | return error; |
441 | } | 441 | } |
442 | 442 | ||
443 | struct xattr_handler xfs_xattr_acl_access_handler = { | 443 | const struct xattr_handler xfs_xattr_acl_access_handler = { |
444 | .prefix = POSIX_ACL_XATTR_ACCESS, | 444 | .prefix = POSIX_ACL_XATTR_ACCESS, |
445 | .flags = ACL_TYPE_ACCESS, | 445 | .flags = ACL_TYPE_ACCESS, |
446 | .get = xfs_xattr_acl_get, | 446 | .get = xfs_xattr_acl_get, |
447 | .set = xfs_xattr_acl_set, | 447 | .set = xfs_xattr_acl_set, |
448 | }; | 448 | }; |
449 | 449 | ||
450 | struct xattr_handler xfs_xattr_acl_default_handler = { | 450 | const struct xattr_handler xfs_xattr_acl_default_handler = { |
451 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 451 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
452 | .flags = ACL_TYPE_DEFAULT, | 452 | .flags = ACL_TYPE_DEFAULT, |
453 | .get = xfs_xattr_acl_get, | 453 | .get = xfs_xattr_acl_get, |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 233d4b9881b1..519618e9279e 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
@@ -85,7 +85,7 @@ extern __uint64_t xfs_max_file_offset(unsigned int); | |||
85 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | 85 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); |
86 | 86 | ||
87 | extern const struct export_operations xfs_export_operations; | 87 | extern const struct export_operations xfs_export_operations; |
88 | extern struct xattr_handler *xfs_xattr_handlers[]; | 88 | extern const struct xattr_handler *xfs_xattr_handlers[]; |
89 | extern const struct quotactl_ops xfs_quotactl_operations; | 89 | extern const struct quotactl_ops xfs_quotactl_operations; |
90 | 90 | ||
91 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) | 91 | #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) |
diff --git a/fs/xfs/linux-2.6/xfs_xattr.c b/fs/xfs/linux-2.6/xfs_xattr.c index fa01b9daba6b..87d3e03878c8 100644 --- a/fs/xfs/linux-2.6/xfs_xattr.c +++ b/fs/xfs/linux-2.6/xfs_xattr.c | |||
@@ -72,28 +72,28 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, | |||
72 | (void *)value, size, xflags); | 72 | (void *)value, size, xflags); |
73 | } | 73 | } |
74 | 74 | ||
75 | static struct xattr_handler xfs_xattr_user_handler = { | 75 | static const struct xattr_handler xfs_xattr_user_handler = { |
76 | .prefix = XATTR_USER_PREFIX, | 76 | .prefix = XATTR_USER_PREFIX, |
77 | .flags = 0, /* no flags implies user namespace */ | 77 | .flags = 0, /* no flags implies user namespace */ |
78 | .get = xfs_xattr_get, | 78 | .get = xfs_xattr_get, |
79 | .set = xfs_xattr_set, | 79 | .set = xfs_xattr_set, |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static struct xattr_handler xfs_xattr_trusted_handler = { | 82 | static const struct xattr_handler xfs_xattr_trusted_handler = { |
83 | .prefix = XATTR_TRUSTED_PREFIX, | 83 | .prefix = XATTR_TRUSTED_PREFIX, |
84 | .flags = ATTR_ROOT, | 84 | .flags = ATTR_ROOT, |
85 | .get = xfs_xattr_get, | 85 | .get = xfs_xattr_get, |
86 | .set = xfs_xattr_set, | 86 | .set = xfs_xattr_set, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct xattr_handler xfs_xattr_security_handler = { | 89 | static const struct xattr_handler xfs_xattr_security_handler = { |
90 | .prefix = XATTR_SECURITY_PREFIX, | 90 | .prefix = XATTR_SECURITY_PREFIX, |
91 | .flags = ATTR_SECURE, | 91 | .flags = ATTR_SECURE, |
92 | .get = xfs_xattr_get, | 92 | .get = xfs_xattr_get, |
93 | .set = xfs_xattr_set, | 93 | .set = xfs_xattr_set, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | struct xattr_handler *xfs_xattr_handlers[] = { | 96 | const struct xattr_handler *xfs_xattr_handlers[] = { |
97 | &xfs_xattr_user_handler, | 97 | &xfs_xattr_user_handler, |
98 | &xfs_xattr_trusted_handler, | 98 | &xfs_xattr_trusted_handler, |
99 | &xfs_xattr_security_handler, | 99 | &xfs_xattr_security_handler, |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index d13eeba2c8f8..0135e2a669d7 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -49,8 +49,8 @@ extern int xfs_acl_chmod(struct inode *inode); | |||
49 | extern int posix_acl_access_exists(struct inode *inode); | 49 | extern int posix_acl_access_exists(struct inode *inode); |
50 | extern int posix_acl_default_exists(struct inode *inode); | 50 | extern int posix_acl_default_exists(struct inode *inode); |
51 | 51 | ||
52 | extern struct xattr_handler xfs_xattr_acl_access_handler; | 52 | extern const struct xattr_handler xfs_xattr_acl_access_handler; |
53 | extern struct xattr_handler xfs_xattr_acl_default_handler; | 53 | extern const struct xattr_handler xfs_xattr_acl_default_handler; |
54 | #else | 54 | #else |
55 | # define xfs_check_acl NULL | 55 | # define xfs_check_acl NULL |
56 | # define xfs_get_acl(inode, type) NULL | 56 | # define xfs_get_acl(inode, type) NULL |