diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 13:34:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 13:34:35 -0400 |
commit | 1193755ac6328ad240ba987e6ec41d5e8baf0680 (patch) | |
tree | 40bf847d7e3ebaa57b107151d14e6cd1d280cc6d /fs | |
parent | 4edebed86690eb8db9af3ab85baf4a34e73266cc (diff) | |
parent | 0ef97dcfce4179a2eba046b855ee2f91d6f1b414 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs changes from Al Viro.
"A lot of misc stuff. The obvious groups:
* Miklos' atomic_open series; kills the damn abuse of
->d_revalidate() by NFS, which was the major stumbling block for
all work in that area.
* ripping security_file_mmap() and dealing with deadlocks in the
area; sanitizing the neighborhood of vm_mmap()/vm_munmap() in
general.
* ->encode_fh() switched to saner API; insane fake dentry in
mm/cleancache.c gone.
* assorted annotations in fs (endianness, __user)
* parts of Artem's ->s_dirty work (jff2 and reiserfs parts)
* ->update_time() work from Josef.
* other bits and pieces all over the place.
Normally it would've been in two or three pull requests, but
signal.git stuff had eaten a lot of time during this cycle ;-/"
Fix up trivial conflicts in Documentation/filesystems/vfs.txt (the
'truncate_range' inode method was removed by the VM changes, the VFS
update adds an 'update_time()' method), and in fs/btrfs/ulist.[ch] (due
to sparse fix added twice, with other changes nearby).
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (95 commits)
nfs: don't open in ->d_revalidate
vfs: retry last component if opening stale dentry
vfs: nameidata_to_filp(): don't throw away file on error
vfs: nameidata_to_filp(): inline __dentry_open()
vfs: do_dentry_open(): don't put filp
vfs: split __dentry_open()
vfs: do_last() common post lookup
vfs: do_last(): add audit_inode before open
vfs: do_last(): only return EISDIR for O_CREAT
vfs: do_last(): check LOOKUP_DIRECTORY
vfs: do_last(): make ENOENT exit RCU safe
vfs: make follow_link check RCU safe
vfs: do_last(): use inode variable
vfs: do_last(): inline walk_component()
vfs: do_last(): make exit RCU safe
vfs: split do_lookup()
Btrfs: move over to use ->update_time
fs: introduce inode operation ->update_time
reiserfs: get rid of resierfs_sync_super
reiserfs: mark the superblock as dirty a bit later
...
Diffstat (limited to 'fs')
89 files changed, 1175 insertions, 1081 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index a1e6c990cd41..e3dd2a1e2bfc 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -68,24 +68,6 @@ static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) | |||
68 | return current_fsgid(); | 68 | return current_fsgid(); |
69 | } | 69 | } |
70 | 70 | ||
71 | /** | ||
72 | * v9fs_dentry_from_dir_inode - helper function to get the dentry from | ||
73 | * dir inode. | ||
74 | * | ||
75 | */ | ||
76 | |||
77 | static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode) | ||
78 | { | ||
79 | struct dentry *dentry; | ||
80 | |||
81 | spin_lock(&inode->i_lock); | ||
82 | /* Directory should have only one entry. */ | ||
83 | BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); | ||
84 | dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); | ||
85 | spin_unlock(&inode->i_lock); | ||
86 | return dentry; | ||
87 | } | ||
88 | |||
89 | static int v9fs_test_inode_dotl(struct inode *inode, void *data) | 71 | static int v9fs_test_inode_dotl(struct inode *inode, void *data) |
90 | { | 72 | { |
91 | struct v9fs_inode *v9inode = V9FS_I(inode); | 73 | struct v9fs_inode *v9inode = V9FS_I(inode); |
@@ -415,7 +397,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
415 | if (dir->i_mode & S_ISGID) | 397 | if (dir->i_mode & S_ISGID) |
416 | omode |= S_ISGID; | 398 | omode |= S_ISGID; |
417 | 399 | ||
418 | dir_dentry = v9fs_dentry_from_dir_inode(dir); | 400 | dir_dentry = dentry->d_parent; |
419 | dfid = v9fs_fid_lookup(dir_dentry); | 401 | dfid = v9fs_fid_lookup(dir_dentry); |
420 | if (IS_ERR(dfid)) { | 402 | if (IS_ERR(dfid)) { |
421 | err = PTR_ERR(dfid); | 403 | err = PTR_ERR(dfid); |
@@ -793,7 +775,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, | |||
793 | dir->i_ino, old_dentry->d_name.name, dentry->d_name.name); | 775 | dir->i_ino, old_dentry->d_name.name, dentry->d_name.name); |
794 | 776 | ||
795 | v9ses = v9fs_inode2v9ses(dir); | 777 | v9ses = v9fs_inode2v9ses(dir); |
796 | dir_dentry = v9fs_dentry_from_dir_inode(dir); | 778 | dir_dentry = dentry->d_parent; |
797 | dfid = v9fs_fid_lookup(dir_dentry); | 779 | dfid = v9fs_fid_lookup(dir_dentry); |
798 | if (IS_ERR(dfid)) | 780 | if (IS_ERR(dfid)) |
799 | return PTR_ERR(dfid); | 781 | return PTR_ERR(dfid); |
@@ -858,7 +840,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
858 | return -EINVAL; | 840 | return -EINVAL; |
859 | 841 | ||
860 | v9ses = v9fs_inode2v9ses(dir); | 842 | v9ses = v9fs_inode2v9ses(dir); |
861 | dir_dentry = v9fs_dentry_from_dir_inode(dir); | 843 | dir_dentry = dentry->d_parent; |
862 | dfid = v9fs_fid_lookup(dir_dentry); | 844 | dfid = v9fs_fid_lookup(dir_dentry); |
863 | if (IS_ERR(dfid)) { | 845 | if (IS_ERR(dfid)) { |
864 | err = PTR_ERR(dfid); | 846 | err = PTR_ERR(dfid); |
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 45a0ce45d7b4..1fceb320d2f2 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -18,14 +18,6 @@ | |||
18 | #define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey]) | 18 | #define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey]) |
19 | #define AFFS_BLOCK(sb, bh, blk) (AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)]) | 19 | #define AFFS_BLOCK(sb, bh, blk) (AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)]) |
20 | 20 | ||
21 | #ifdef __LITTLE_ENDIAN | ||
22 | #define BO_EXBITS 0x18UL | ||
23 | #elif defined(__BIG_ENDIAN) | ||
24 | #define BO_EXBITS 0x00UL | ||
25 | #else | ||
26 | #error Endianness must be known for affs to work. | ||
27 | #endif | ||
28 | |||
29 | #define AFFS_HEAD(bh) ((struct affs_head *)(bh)->b_data) | 21 | #define AFFS_HEAD(bh) ((struct affs_head *)(bh)->b_data) |
30 | #define AFFS_TAIL(sb, bh) ((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail))) | 22 | #define AFFS_TAIL(sb, bh) ((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail))) |
31 | #define AFFS_ROOT_HEAD(bh) ((struct affs_root_head *)(bh)->b_data) | 23 | #define AFFS_ROOT_HEAD(bh) ((struct affs_root_head *)(bh)->b_data) |
@@ -134,9 +134,9 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
134 | info->mmap_size = nr_pages * PAGE_SIZE; | 134 | info->mmap_size = nr_pages * PAGE_SIZE; |
135 | dprintk("attempting mmap of %lu bytes\n", info->mmap_size); | 135 | dprintk("attempting mmap of %lu bytes\n", info->mmap_size); |
136 | down_write(&ctx->mm->mmap_sem); | 136 | down_write(&ctx->mm->mmap_sem); |
137 | info->mmap_base = do_mmap(NULL, 0, info->mmap_size, | 137 | info->mmap_base = do_mmap_pgoff(NULL, 0, info->mmap_size, |
138 | PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, | 138 | PROT_READ|PROT_WRITE, |
139 | 0); | 139 | MAP_ANONYMOUS|MAP_PRIVATE, 0); |
140 | if (IS_ERR((void *)info->mmap_base)) { | 140 | if (IS_ERR((void *)info->mmap_base)) { |
141 | up_write(&ctx->mm->mmap_sem); | 141 | up_write(&ctx->mm->mmap_sem); |
142 | info->mmap_size = 0; | 142 | info->mmap_size = 0; |
@@ -176,6 +176,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
176 | return -EPERM; | 176 | return -EPERM; |
177 | } | 177 | } |
178 | 178 | ||
179 | if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) { | ||
180 | if (attr->ia_size != inode->i_size) | ||
181 | inode_inc_iversion(inode); | ||
182 | } | ||
183 | |||
179 | if ((ia_valid & ATTR_MODE)) { | 184 | if ((ia_valid & ATTR_MODE)) { |
180 | umode_t amode = attr->ia_mode; | 185 | umode_t amode = attr->ia_mode; |
181 | /* Flag setting protected by i_mutex */ | 186 | /* Flag setting protected by i_mutex */ |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index e658dd134b95..1b52956afe33 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -329,7 +329,6 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, | |||
329 | if (!size) | 329 | if (!size) |
330 | return addr; | 330 | return addr; |
331 | 331 | ||
332 | down_write(¤t->mm->mmap_sem); | ||
333 | /* | 332 | /* |
334 | * total_size is the size of the ELF (interpreter) image. | 333 | * total_size is the size of the ELF (interpreter) image. |
335 | * The _first_ mmap needs to know the full size, otherwise | 334 | * The _first_ mmap needs to know the full size, otherwise |
@@ -340,13 +339,12 @@ static unsigned long elf_map(struct file *filep, unsigned long addr, | |||
340 | */ | 339 | */ |
341 | if (total_size) { | 340 | if (total_size) { |
342 | total_size = ELF_PAGEALIGN(total_size); | 341 | total_size = ELF_PAGEALIGN(total_size); |
343 | map_addr = do_mmap(filep, addr, total_size, prot, type, off); | 342 | map_addr = vm_mmap(filep, addr, total_size, prot, type, off); |
344 | if (!BAD_ADDR(map_addr)) | 343 | if (!BAD_ADDR(map_addr)) |
345 | do_munmap(current->mm, map_addr+size, total_size-size); | 344 | vm_munmap(map_addr+size, total_size-size); |
346 | } else | 345 | } else |
347 | map_addr = do_mmap(filep, addr, size, prot, type, off); | 346 | map_addr = vm_mmap(filep, addr, size, prot, type, off); |
348 | 347 | ||
349 | up_write(¤t->mm->mmap_sem); | ||
350 | return(map_addr); | 348 | return(map_addr); |
351 | } | 349 | } |
352 | 350 | ||
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 6b2daf99fab8..178cb70acc26 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -562,7 +562,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
562 | realdatastart = (unsigned long) -ENOMEM; | 562 | realdatastart = (unsigned long) -ENOMEM; |
563 | printk("Unable to allocate RAM for process data, errno %d\n", | 563 | printk("Unable to allocate RAM for process data, errno %d\n", |
564 | (int)-realdatastart); | 564 | (int)-realdatastart); |
565 | do_munmap(current->mm, textpos, text_len); | 565 | vm_munmap(textpos, text_len); |
566 | ret = realdatastart; | 566 | ret = realdatastart; |
567 | goto err; | 567 | goto err; |
568 | } | 568 | } |
@@ -586,8 +586,8 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
586 | } | 586 | } |
587 | if (IS_ERR_VALUE(result)) { | 587 | if (IS_ERR_VALUE(result)) { |
588 | printk("Unable to read data+bss, errno %d\n", (int)-result); | 588 | printk("Unable to read data+bss, errno %d\n", (int)-result); |
589 | do_munmap(current->mm, textpos, text_len); | 589 | vm_munmap(textpos, text_len); |
590 | do_munmap(current->mm, realdatastart, len); | 590 | vm_munmap(realdatastart, len); |
591 | ret = result; | 591 | ret = result; |
592 | goto err; | 592 | goto err; |
593 | } | 593 | } |
@@ -654,7 +654,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
654 | } | 654 | } |
655 | if (IS_ERR_VALUE(result)) { | 655 | if (IS_ERR_VALUE(result)) { |
656 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); | 656 | printk("Unable to read code+data+bss, errno %d\n",(int)-result); |
657 | do_munmap(current->mm, textpos, text_len + data_len + extra + | 657 | vm_munmap(textpos, text_len + data_len + extra + |
658 | MAX_SHARED_LIBS * sizeof(unsigned long)); | 658 | MAX_SHARED_LIBS * sizeof(unsigned long)); |
659 | ret = result; | 659 | ret = result; |
660 | goto err; | 660 | goto err; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0151ca1ac657..0236d03c6732 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2974,7 +2974,6 @@ int btrfs_readpage(struct file *file, struct page *page); | |||
2974 | void btrfs_evict_inode(struct inode *inode); | 2974 | void btrfs_evict_inode(struct inode *inode); |
2975 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); | 2975 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2976 | int btrfs_dirty_inode(struct inode *inode); | 2976 | int btrfs_dirty_inode(struct inode *inode); |
2977 | int btrfs_update_time(struct file *file); | ||
2978 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2977 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2979 | void btrfs_destroy_inode(struct inode *inode); | 2978 | void btrfs_destroy_inode(struct inode *inode); |
2980 | int btrfs_drop_inode(struct inode *inode); | 2979 | int btrfs_drop_inode(struct inode *inode); |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index e887ee62b6d4..614f34a899c2 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -13,15 +13,14 @@ | |||
13 | parent_root_objectid) / 4) | 13 | parent_root_objectid) / 4) |
14 | #define BTRFS_FID_SIZE_CONNECTABLE_ROOT (sizeof(struct btrfs_fid) / 4) | 14 | #define BTRFS_FID_SIZE_CONNECTABLE_ROOT (sizeof(struct btrfs_fid) / 4) |
15 | 15 | ||
16 | static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | 16 | static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, |
17 | int connectable) | 17 | struct inode *parent) |
18 | { | 18 | { |
19 | struct btrfs_fid *fid = (struct btrfs_fid *)fh; | 19 | struct btrfs_fid *fid = (struct btrfs_fid *)fh; |
20 | struct inode *inode = dentry->d_inode; | ||
21 | int len = *max_len; | 20 | int len = *max_len; |
22 | int type; | 21 | int type; |
23 | 22 | ||
24 | if (connectable && (len < BTRFS_FID_SIZE_CONNECTABLE)) { | 23 | if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) { |
25 | *max_len = BTRFS_FID_SIZE_CONNECTABLE; | 24 | *max_len = BTRFS_FID_SIZE_CONNECTABLE; |
26 | return 255; | 25 | return 255; |
27 | } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { | 26 | } else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) { |
@@ -36,19 +35,13 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
36 | fid->root_objectid = BTRFS_I(inode)->root->objectid; | 35 | fid->root_objectid = BTRFS_I(inode)->root->objectid; |
37 | fid->gen = inode->i_generation; | 36 | fid->gen = inode->i_generation; |
38 | 37 | ||
39 | if (connectable && !S_ISDIR(inode->i_mode)) { | 38 | if (parent) { |
40 | struct inode *parent; | ||
41 | u64 parent_root_id; | 39 | u64 parent_root_id; |
42 | 40 | ||
43 | spin_lock(&dentry->d_lock); | ||
44 | |||
45 | parent = dentry->d_parent->d_inode; | ||
46 | fid->parent_objectid = BTRFS_I(parent)->location.objectid; | 41 | fid->parent_objectid = BTRFS_I(parent)->location.objectid; |
47 | fid->parent_gen = parent->i_generation; | 42 | fid->parent_gen = parent->i_generation; |
48 | parent_root_id = BTRFS_I(parent)->root->objectid; | 43 | parent_root_id = BTRFS_I(parent)->root->objectid; |
49 | 44 | ||
50 | spin_unlock(&dentry->d_lock); | ||
51 | |||
52 | if (parent_root_id != fid->root_objectid) { | 45 | if (parent_root_id != fid->root_objectid) { |
53 | fid->parent_root_objectid = parent_root_id; | 46 | fid->parent_root_objectid = parent_root_id; |
54 | len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; | 47 | len = BTRFS_FID_SIZE_CONNECTABLE_ROOT; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 876cddd6b2f0..70dc8ca73e25 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1433,7 +1433,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
1433 | goto out; | 1433 | goto out; |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | err = btrfs_update_time(file); | 1436 | err = file_update_time(file); |
1437 | if (err) { | 1437 | if (err) { |
1438 | mutex_unlock(&inode->i_mutex); | 1438 | mutex_unlock(&inode->i_mutex); |
1439 | goto out; | 1439 | goto out; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 19a0d85b451c..81296c57405a 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -77,7 +77,8 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, | |||
77 | return ERR_PTR(-ENOENT); | 77 | return ERR_PTR(-ENOENT); |
78 | } | 78 | } |
79 | 79 | ||
80 | inode->i_mapping->flags &= ~__GFP_FS; | 80 | mapping_set_gfp_mask(inode->i_mapping, |
81 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | ||
81 | 82 | ||
82 | return inode; | 83 | return inode; |
83 | } | 84 | } |
@@ -367,7 +368,7 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode, | |||
367 | 368 | ||
368 | static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation) | 369 | static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation) |
369 | { | 370 | { |
370 | u64 *val; | 371 | __le64 *val; |
371 | 372 | ||
372 | io_ctl_map_page(io_ctl, 1); | 373 | io_ctl_map_page(io_ctl, 1); |
373 | 374 | ||
@@ -390,7 +391,7 @@ static void io_ctl_set_generation(struct io_ctl *io_ctl, u64 generation) | |||
390 | 391 | ||
391 | static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation) | 392 | static int io_ctl_check_generation(struct io_ctl *io_ctl, u64 generation) |
392 | { | 393 | { |
393 | u64 *gen; | 394 | __le64 *gen; |
394 | 395 | ||
395 | /* | 396 | /* |
396 | * Skip the crc area. If we don't check crcs then we just have a 64bit | 397 | * Skip the crc area. If we don't check crcs then we just have a 64bit |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e9991adc0960..f6ab6f5e635a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4475,46 +4475,18 @@ int btrfs_dirty_inode(struct inode *inode) | |||
4475 | * This is a copy of file_update_time. We need this so we can return error on | 4475 | * This is a copy of file_update_time. We need this so we can return error on |
4476 | * ENOSPC for updating the inode in the case of file write and mmap writes. | 4476 | * ENOSPC for updating the inode in the case of file write and mmap writes. |
4477 | */ | 4477 | */ |
4478 | int btrfs_update_time(struct file *file) | 4478 | static int btrfs_update_time(struct inode *inode, struct timespec *now, |
4479 | int flags) | ||
4479 | { | 4480 | { |
4480 | struct inode *inode = file->f_path.dentry->d_inode; | 4481 | if (flags & S_VERSION) |
4481 | struct timespec now; | ||
4482 | int ret; | ||
4483 | enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; | ||
4484 | |||
4485 | /* First try to exhaust all avenues to not sync */ | ||
4486 | if (IS_NOCMTIME(inode)) | ||
4487 | return 0; | ||
4488 | |||
4489 | now = current_fs_time(inode->i_sb); | ||
4490 | if (!timespec_equal(&inode->i_mtime, &now)) | ||
4491 | sync_it = S_MTIME; | ||
4492 | |||
4493 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
4494 | sync_it |= S_CTIME; | ||
4495 | |||
4496 | if (IS_I_VERSION(inode)) | ||
4497 | sync_it |= S_VERSION; | ||
4498 | |||
4499 | if (!sync_it) | ||
4500 | return 0; | ||
4501 | |||
4502 | /* Finally allowed to write? Takes lock. */ | ||
4503 | if (mnt_want_write_file(file)) | ||
4504 | return 0; | ||
4505 | |||
4506 | /* Only change inode inside the lock region */ | ||
4507 | if (sync_it & S_VERSION) | ||
4508 | inode_inc_iversion(inode); | 4482 | inode_inc_iversion(inode); |
4509 | if (sync_it & S_CTIME) | 4483 | if (flags & S_CTIME) |
4510 | inode->i_ctime = now; | 4484 | inode->i_ctime = *now; |
4511 | if (sync_it & S_MTIME) | 4485 | if (flags & S_MTIME) |
4512 | inode->i_mtime = now; | 4486 | inode->i_mtime = *now; |
4513 | ret = btrfs_dirty_inode(inode); | 4487 | if (flags & S_ATIME) |
4514 | if (!ret) | 4488 | inode->i_atime = *now; |
4515 | mark_inode_dirty_sync(inode); | 4489 | return btrfs_dirty_inode(inode); |
4516 | mnt_drop_write(file->f_path.mnt); | ||
4517 | return ret; | ||
4518 | } | 4490 | } |
4519 | 4491 | ||
4520 | /* | 4492 | /* |
@@ -6565,7 +6537,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
6565 | 6537 | ||
6566 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); | 6538 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
6567 | if (!ret) { | 6539 | if (!ret) { |
6568 | ret = btrfs_update_time(vma->vm_file); | 6540 | ret = file_update_time(vma->vm_file); |
6569 | reserved = 1; | 6541 | reserved = 1; |
6570 | } | 6542 | } |
6571 | if (ret) { | 6543 | if (ret) { |
@@ -7635,6 +7607,7 @@ static const struct inode_operations btrfs_file_inode_operations = { | |||
7635 | .permission = btrfs_permission, | 7607 | .permission = btrfs_permission, |
7636 | .fiemap = btrfs_fiemap, | 7608 | .fiemap = btrfs_fiemap, |
7637 | .get_acl = btrfs_get_acl, | 7609 | .get_acl = btrfs_get_acl, |
7610 | .update_time = btrfs_update_time, | ||
7638 | }; | 7611 | }; |
7639 | static const struct inode_operations btrfs_special_inode_operations = { | 7612 | static const struct inode_operations btrfs_special_inode_operations = { |
7640 | .getattr = btrfs_getattr, | 7613 | .getattr = btrfs_getattr, |
@@ -7645,6 +7618,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
7645 | .listxattr = btrfs_listxattr, | 7618 | .listxattr = btrfs_listxattr, |
7646 | .removexattr = btrfs_removexattr, | 7619 | .removexattr = btrfs_removexattr, |
7647 | .get_acl = btrfs_get_acl, | 7620 | .get_acl = btrfs_get_acl, |
7621 | .update_time = btrfs_update_time, | ||
7648 | }; | 7622 | }; |
7649 | static const struct inode_operations btrfs_symlink_inode_operations = { | 7623 | static const struct inode_operations btrfs_symlink_inode_operations = { |
7650 | .readlink = generic_readlink, | 7624 | .readlink = generic_readlink, |
@@ -7658,6 +7632,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
7658 | .listxattr = btrfs_listxattr, | 7632 | .listxattr = btrfs_listxattr, |
7659 | .removexattr = btrfs_removexattr, | 7633 | .removexattr = btrfs_removexattr, |
7660 | .get_acl = btrfs_get_acl, | 7634 | .get_acl = btrfs_get_acl, |
7635 | .update_time = btrfs_update_time, | ||
7661 | }; | 7636 | }; |
7662 | 7637 | ||
7663 | const struct dentry_operations btrfs_dentry_operations = { | 7638 | const struct dentry_operations btrfs_dentry_operations = { |
diff --git a/fs/buffer.c b/fs/buffer.c index ad5938ca357c..838a9cf246bd 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -3152,7 +3152,7 @@ SYSCALL_DEFINE2(bdflush, int, func, long, data) | |||
3152 | /* | 3152 | /* |
3153 | * Buffer-head allocation | 3153 | * Buffer-head allocation |
3154 | */ | 3154 | */ |
3155 | static struct kmem_cache *bh_cachep; | 3155 | static struct kmem_cache *bh_cachep __read_mostly; |
3156 | 3156 | ||
3157 | /* | 3157 | /* |
3158 | * Once the number of bh's in the machine exceeds this level, we start | 3158 | * Once the number of bh's in the machine exceeds this level, we start |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index fbb2a643ef10..8e1b60e557b6 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -40,38 +40,49 @@ struct ceph_nfs_confh { | |||
40 | u32 parent_name_hash; | 40 | u32 parent_name_hash; |
41 | } __attribute__ ((packed)); | 41 | } __attribute__ ((packed)); |
42 | 42 | ||
43 | static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | 43 | /* |
44 | int connectable) | 44 | * The presence of @parent_inode here tells us whether NFS wants a |
45 | * connectable file handle. However, we want to make a connectionable | ||
46 | * file handle unconditionally so that the MDS gets as much of a hint | ||
47 | * as possible. That means we only use @parent_dentry to indicate | ||
48 | * whether nfsd wants a connectable fh, and whether we should indicate | ||
49 | * failure from a too-small @max_len. | ||
50 | */ | ||
51 | static int ceph_encode_fh(struct inode *inode, u32 *rawfh, int *max_len, | ||
52 | struct inode *parent_inode) | ||
45 | { | 53 | { |
46 | int type; | 54 | int type; |
47 | struct ceph_nfs_fh *fh = (void *)rawfh; | 55 | struct ceph_nfs_fh *fh = (void *)rawfh; |
48 | struct ceph_nfs_confh *cfh = (void *)rawfh; | 56 | struct ceph_nfs_confh *cfh = (void *)rawfh; |
49 | struct dentry *parent; | ||
50 | struct inode *inode = dentry->d_inode; | ||
51 | int connected_handle_length = sizeof(*cfh)/4; | 57 | int connected_handle_length = sizeof(*cfh)/4; |
52 | int handle_length = sizeof(*fh)/4; | 58 | int handle_length = sizeof(*fh)/4; |
59 | struct dentry *dentry = d_find_alias(inode); | ||
60 | struct dentry *parent; | ||
53 | 61 | ||
54 | /* don't re-export snaps */ | 62 | /* don't re-export snaps */ |
55 | if (ceph_snap(inode) != CEPH_NOSNAP) | 63 | if (ceph_snap(inode) != CEPH_NOSNAP) |
56 | return -EINVAL; | 64 | return -EINVAL; |
57 | 65 | ||
58 | spin_lock(&dentry->d_lock); | 66 | /* if we found an alias, generate a connectable fh */ |
59 | parent = dentry->d_parent; | 67 | if (*max_len >= connected_handle_length && dentry) { |
60 | if (*max_len >= connected_handle_length) { | ||
61 | dout("encode_fh %p connectable\n", dentry); | 68 | dout("encode_fh %p connectable\n", dentry); |
62 | cfh->ino = ceph_ino(dentry->d_inode); | 69 | spin_lock(&dentry->d_lock); |
70 | parent = dentry->d_parent; | ||
71 | cfh->ino = ceph_ino(inode); | ||
63 | cfh->parent_ino = ceph_ino(parent->d_inode); | 72 | cfh->parent_ino = ceph_ino(parent->d_inode); |
64 | cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode, | 73 | cfh->parent_name_hash = ceph_dentry_hash(parent->d_inode, |
65 | dentry); | 74 | dentry); |
66 | *max_len = connected_handle_length; | 75 | *max_len = connected_handle_length; |
67 | type = 2; | 76 | type = 2; |
77 | spin_unlock(&dentry->d_lock); | ||
68 | } else if (*max_len >= handle_length) { | 78 | } else if (*max_len >= handle_length) { |
69 | if (connectable) { | 79 | if (parent_inode) { |
80 | /* nfsd wants connectable */ | ||
70 | *max_len = connected_handle_length; | 81 | *max_len = connected_handle_length; |
71 | type = 255; | 82 | type = 255; |
72 | } else { | 83 | } else { |
73 | dout("encode_fh %p\n", dentry); | 84 | dout("encode_fh %p\n", dentry); |
74 | fh->ino = ceph_ino(dentry->d_inode); | 85 | fh->ino = ceph_ino(inode); |
75 | *max_len = handle_length; | 86 | *max_len = handle_length; |
76 | type = 1; | 87 | type = 1; |
77 | } | 88 | } |
@@ -79,7 +90,6 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | |||
79 | *max_len = handle_length; | 90 | *max_len = handle_length; |
80 | type = 255; | 91 | type = 255; |
81 | } | 92 | } |
82 | spin_unlock(&dentry->d_lock); | ||
83 | return type; | 93 | return type; |
84 | } | 94 | } |
85 | 95 | ||
diff --git a/fs/compat.c b/fs/compat.c index 6556a9ce8a28..3004d2bad13f 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -871,12 +871,12 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
871 | { | 871 | { |
872 | int error; | 872 | int error; |
873 | struct file *file; | 873 | struct file *file; |
874 | int fput_needed; | ||
874 | struct compat_readdir_callback buf; | 875 | struct compat_readdir_callback buf; |
875 | 876 | ||
876 | error = -EBADF; | 877 | file = fget_light(fd, &fput_needed); |
877 | file = fget(fd); | ||
878 | if (!file) | 878 | if (!file) |
879 | goto out; | 879 | return -EBADF; |
880 | 880 | ||
881 | buf.result = 0; | 881 | buf.result = 0; |
882 | buf.dirent = dirent; | 882 | buf.dirent = dirent; |
@@ -885,8 +885,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
885 | if (buf.result) | 885 | if (buf.result) |
886 | error = buf.result; | 886 | error = buf.result; |
887 | 887 | ||
888 | fput(file); | 888 | fput_light(file, fput_needed); |
889 | out: | ||
890 | return error; | 889 | return error; |
891 | } | 890 | } |
892 | 891 | ||
@@ -953,16 +952,15 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
953 | struct file * file; | 952 | struct file * file; |
954 | struct compat_linux_dirent __user * lastdirent; | 953 | struct compat_linux_dirent __user * lastdirent; |
955 | struct compat_getdents_callback buf; | 954 | struct compat_getdents_callback buf; |
955 | int fput_needed; | ||
956 | int error; | 956 | int error; |
957 | 957 | ||
958 | error = -EFAULT; | ||
959 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 958 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
960 | goto out; | 959 | return -EFAULT; |
961 | 960 | ||
962 | error = -EBADF; | 961 | file = fget_light(fd, &fput_needed); |
963 | file = fget(fd); | ||
964 | if (!file) | 962 | if (!file) |
965 | goto out; | 963 | return -EBADF; |
966 | 964 | ||
967 | buf.current_dir = dirent; | 965 | buf.current_dir = dirent; |
968 | buf.previous = NULL; | 966 | buf.previous = NULL; |
@@ -979,8 +977,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
979 | else | 977 | else |
980 | error = count - buf.count; | 978 | error = count - buf.count; |
981 | } | 979 | } |
982 | fput(file); | 980 | fput_light(file, fput_needed); |
983 | out: | ||
984 | return error; | 981 | return error; |
985 | } | 982 | } |
986 | 983 | ||
@@ -1041,16 +1038,15 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1041 | struct file * file; | 1038 | struct file * file; |
1042 | struct linux_dirent64 __user * lastdirent; | 1039 | struct linux_dirent64 __user * lastdirent; |
1043 | struct compat_getdents_callback64 buf; | 1040 | struct compat_getdents_callback64 buf; |
1041 | int fput_needed; | ||
1044 | int error; | 1042 | int error; |
1045 | 1043 | ||
1046 | error = -EFAULT; | ||
1047 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 1044 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
1048 | goto out; | 1045 | return -EFAULT; |
1049 | 1046 | ||
1050 | error = -EBADF; | 1047 | file = fget_light(fd, &fput_needed); |
1051 | file = fget(fd); | ||
1052 | if (!file) | 1048 | if (!file) |
1053 | goto out; | 1049 | return -EBADF; |
1054 | 1050 | ||
1055 | buf.current_dir = dirent; | 1051 | buf.current_dir = dirent; |
1056 | buf.previous = NULL; | 1052 | buf.previous = NULL; |
@@ -1068,8 +1064,7 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1068 | else | 1064 | else |
1069 | error = count - buf.count; | 1065 | error = count - buf.count; |
1070 | } | 1066 | } |
1071 | fput(file); | 1067 | fput_light(file, fput_needed); |
1072 | out: | ||
1073 | return error; | 1068 | return error; |
1074 | } | 1069 | } |
1075 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ | 1070 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ |
diff --git a/fs/dcache.c b/fs/dcache.c index 4435d8b32904..85c9e2bff8e6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -683,8 +683,6 @@ EXPORT_SYMBOL(dget_parent); | |||
683 | /** | 683 | /** |
684 | * d_find_alias - grab a hashed alias of inode | 684 | * d_find_alias - grab a hashed alias of inode |
685 | * @inode: inode in question | 685 | * @inode: inode in question |
686 | * @want_discon: flag, used by d_splice_alias, to request | ||
687 | * that only a DISCONNECTED alias be returned. | ||
688 | * | 686 | * |
689 | * If inode has a hashed alias, or is a directory and has any alias, | 687 | * If inode has a hashed alias, or is a directory and has any alias, |
690 | * acquire the reference to alias and return it. Otherwise return NULL. | 688 | * acquire the reference to alias and return it. Otherwise return NULL. |
@@ -693,10 +691,9 @@ EXPORT_SYMBOL(dget_parent); | |||
693 | * of a filesystem. | 691 | * of a filesystem. |
694 | * | 692 | * |
695 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer | 693 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer |
696 | * any other hashed alias over that one unless @want_discon is set, | 694 | * any other hashed alias over that. |
697 | * in which case only return an IS_ROOT, DCACHE_DISCONNECTED alias. | ||
698 | */ | 695 | */ |
699 | static struct dentry *__d_find_alias(struct inode *inode, int want_discon) | 696 | static struct dentry *__d_find_alias(struct inode *inode) |
700 | { | 697 | { |
701 | struct dentry *alias, *discon_alias; | 698 | struct dentry *alias, *discon_alias; |
702 | 699 | ||
@@ -708,7 +705,7 @@ again: | |||
708 | if (IS_ROOT(alias) && | 705 | if (IS_ROOT(alias) && |
709 | (alias->d_flags & DCACHE_DISCONNECTED)) { | 706 | (alias->d_flags & DCACHE_DISCONNECTED)) { |
710 | discon_alias = alias; | 707 | discon_alias = alias; |
711 | } else if (!want_discon) { | 708 | } else { |
712 | __dget_dlock(alias); | 709 | __dget_dlock(alias); |
713 | spin_unlock(&alias->d_lock); | 710 | spin_unlock(&alias->d_lock); |
714 | return alias; | 711 | return alias; |
@@ -739,7 +736,7 @@ struct dentry *d_find_alias(struct inode *inode) | |||
739 | 736 | ||
740 | if (!list_empty(&inode->i_dentry)) { | 737 | if (!list_empty(&inode->i_dentry)) { |
741 | spin_lock(&inode->i_lock); | 738 | spin_lock(&inode->i_lock); |
742 | de = __d_find_alias(inode, 0); | 739 | de = __d_find_alias(inode); |
743 | spin_unlock(&inode->i_lock); | 740 | spin_unlock(&inode->i_lock); |
744 | } | 741 | } |
745 | return de; | 742 | return de; |
@@ -1650,9 +1647,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
1650 | 1647 | ||
1651 | if (inode && S_ISDIR(inode->i_mode)) { | 1648 | if (inode && S_ISDIR(inode->i_mode)) { |
1652 | spin_lock(&inode->i_lock); | 1649 | spin_lock(&inode->i_lock); |
1653 | new = __d_find_alias(inode, 1); | 1650 | new = __d_find_any_alias(inode); |
1654 | if (new) { | 1651 | if (new) { |
1655 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); | ||
1656 | spin_unlock(&inode->i_lock); | 1652 | spin_unlock(&inode->i_lock); |
1657 | security_d_instantiate(new, inode); | 1653 | security_d_instantiate(new, inode); |
1658 | d_move(new, dentry); | 1654 | d_move(new, dentry); |
@@ -2482,7 +2478,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2482 | struct dentry *alias; | 2478 | struct dentry *alias; |
2483 | 2479 | ||
2484 | /* Does an aliased dentry already exist? */ | 2480 | /* Does an aliased dentry already exist? */ |
2485 | alias = __d_find_alias(inode, 0); | 2481 | alias = __d_find_alias(inode); |
2486 | if (alias) { | 2482 | if (alias) { |
2487 | actual = alias; | 2483 | actual = alias; |
2488 | write_seqlock(&rename_lock); | 2484 | write_seqlock(&rename_lock); |
@@ -2575,7 +2571,7 @@ static int prepend_path(const struct path *path, | |||
2575 | bool slash = false; | 2571 | bool slash = false; |
2576 | int error = 0; | 2572 | int error = 0; |
2577 | 2573 | ||
2578 | br_read_lock(vfsmount_lock); | 2574 | br_read_lock(&vfsmount_lock); |
2579 | while (dentry != root->dentry || vfsmnt != root->mnt) { | 2575 | while (dentry != root->dentry || vfsmnt != root->mnt) { |
2580 | struct dentry * parent; | 2576 | struct dentry * parent; |
2581 | 2577 | ||
@@ -2606,7 +2602,7 @@ static int prepend_path(const struct path *path, | |||
2606 | error = prepend(buffer, buflen, "/", 1); | 2602 | error = prepend(buffer, buflen, "/", 1); |
2607 | 2603 | ||
2608 | out: | 2604 | out: |
2609 | br_read_unlock(vfsmount_lock); | 2605 | br_read_unlock(&vfsmount_lock); |
2610 | return error; | 2606 | return error; |
2611 | 2607 | ||
2612 | global_root: | 2608 | global_root: |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index ab35b113003b..a07441a0a878 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -660,11 +660,10 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, | |||
660 | { | 660 | { |
661 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 661 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
662 | char *lower_buf; | 662 | char *lower_buf; |
663 | size_t lower_bufsiz = PATH_MAX; | ||
664 | mm_segment_t old_fs; | 663 | mm_segment_t old_fs; |
665 | int rc; | 664 | int rc; |
666 | 665 | ||
667 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); | 666 | lower_buf = kmalloc(PATH_MAX, GFP_KERNEL); |
668 | if (!lower_buf) { | 667 | if (!lower_buf) { |
669 | rc = -ENOMEM; | 668 | rc = -ENOMEM; |
670 | goto out; | 669 | goto out; |
@@ -673,58 +672,29 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, | |||
673 | set_fs(get_ds()); | 672 | set_fs(get_ds()); |
674 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, | 673 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, |
675 | (char __user *)lower_buf, | 674 | (char __user *)lower_buf, |
676 | lower_bufsiz); | 675 | PATH_MAX); |
677 | set_fs(old_fs); | 676 | set_fs(old_fs); |
678 | if (rc < 0) | 677 | if (rc < 0) |
679 | goto out; | 678 | goto out; |
680 | lower_bufsiz = rc; | ||
681 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, | 679 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, |
682 | lower_buf, lower_bufsiz); | 680 | lower_buf, rc); |
683 | out: | 681 | out: |
684 | kfree(lower_buf); | 682 | kfree(lower_buf); |
685 | return rc; | 683 | return rc; |
686 | } | 684 | } |
687 | 685 | ||
688 | static int | 686 | static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
689 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | ||
690 | { | 687 | { |
691 | char *kbuf; | 688 | char *buf; |
692 | size_t kbufsiz, copied; | 689 | size_t len = PATH_MAX; |
693 | int rc; | 690 | int rc; |
694 | 691 | ||
695 | rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); | 692 | rc = ecryptfs_readlink_lower(dentry, &buf, &len); |
696 | if (rc) | 693 | if (rc) |
697 | goto out; | 694 | goto out; |
698 | copied = min_t(size_t, bufsiz, kbufsiz); | ||
699 | rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied; | ||
700 | kfree(kbuf); | ||
701 | fsstack_copy_attr_atime(dentry->d_inode, | 695 | fsstack_copy_attr_atime(dentry->d_inode, |
702 | ecryptfs_dentry_to_lower(dentry)->d_inode); | 696 | ecryptfs_dentry_to_lower(dentry)->d_inode); |
703 | out: | 697 | buf[len] = '\0'; |
704 | return rc; | ||
705 | } | ||
706 | |||
707 | static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
708 | { | ||
709 | char *buf; | ||
710 | int len = PAGE_SIZE, rc; | ||
711 | mm_segment_t old_fs; | ||
712 | |||
713 | /* Released in ecryptfs_put_link(); only release here on error */ | ||
714 | buf = kmalloc(len, GFP_KERNEL); | ||
715 | if (!buf) { | ||
716 | buf = ERR_PTR(-ENOMEM); | ||
717 | goto out; | ||
718 | } | ||
719 | old_fs = get_fs(); | ||
720 | set_fs(get_ds()); | ||
721 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); | ||
722 | set_fs(old_fs); | ||
723 | if (rc < 0) { | ||
724 | kfree(buf); | ||
725 | buf = ERR_PTR(rc); | ||
726 | } else | ||
727 | buf[rc] = '\0'; | ||
728 | out: | 698 | out: |
729 | nd_set_link(nd, buf); | 699 | nd_set_link(nd, buf); |
730 | return NULL; | 700 | return NULL; |
@@ -1153,7 +1123,7 @@ out: | |||
1153 | } | 1123 | } |
1154 | 1124 | ||
1155 | const struct inode_operations ecryptfs_symlink_iops = { | 1125 | const struct inode_operations ecryptfs_symlink_iops = { |
1156 | .readlink = ecryptfs_readlink, | 1126 | .readlink = generic_readlink, |
1157 | .follow_link = ecryptfs_follow_link, | 1127 | .follow_link = ecryptfs_follow_link, |
1158 | .put_link = ecryptfs_put_link, | 1128 | .put_link = ecryptfs_put_link, |
1159 | .permission = ecryptfs_permission, | 1129 | .permission = ecryptfs_permission, |
@@ -280,10 +280,6 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
280 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 280 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
281 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 281 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
282 | 282 | ||
283 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
284 | if (err) | ||
285 | goto err; | ||
286 | |||
287 | err = insert_vm_struct(mm, vma); | 283 | err = insert_vm_struct(mm, vma); |
288 | if (err) | 284 | if (err) |
289 | goto err; | 285 | goto err; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index b05acb796135..b0201ca6e9c6 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -304,24 +304,23 @@ out: | |||
304 | 304 | ||
305 | /** | 305 | /** |
306 | * export_encode_fh - default export_operations->encode_fh function | 306 | * export_encode_fh - default export_operations->encode_fh function |
307 | * @dentry: the dentry to encode | 307 | * @inode: the object to encode |
308 | * @fh: where to store the file handle fragment | 308 | * @fh: where to store the file handle fragment |
309 | * @max_len: maximum length to store there | 309 | * @max_len: maximum length to store there |
310 | * @connectable: whether to store parent information | 310 | * @parent: parent directory inode, if wanted |
311 | * | 311 | * |
312 | * This default encode_fh function assumes that the 32 inode number | 312 | * This default encode_fh function assumes that the 32 inode number |
313 | * is suitable for locating an inode, and that the generation number | 313 | * is suitable for locating an inode, and that the generation number |
314 | * can be used to check that it is still valid. It places them in the | 314 | * can be used to check that it is still valid. It places them in the |
315 | * filehandle fragment where export_decode_fh expects to find them. | 315 | * filehandle fragment where export_decode_fh expects to find them. |
316 | */ | 316 | */ |
317 | static int export_encode_fh(struct dentry *dentry, struct fid *fid, | 317 | static int export_encode_fh(struct inode *inode, struct fid *fid, |
318 | int *max_len, int connectable) | 318 | int *max_len, struct inode *parent) |
319 | { | 319 | { |
320 | struct inode * inode = dentry->d_inode; | ||
321 | int len = *max_len; | 320 | int len = *max_len; |
322 | int type = FILEID_INO32_GEN; | 321 | int type = FILEID_INO32_GEN; |
323 | 322 | ||
324 | if (connectable && (len < 4)) { | 323 | if (parent && (len < 4)) { |
325 | *max_len = 4; | 324 | *max_len = 4; |
326 | return 255; | 325 | return 255; |
327 | } else if (len < 2) { | 326 | } else if (len < 2) { |
@@ -332,14 +331,9 @@ static int export_encode_fh(struct dentry *dentry, struct fid *fid, | |||
332 | len = 2; | 331 | len = 2; |
333 | fid->i32.ino = inode->i_ino; | 332 | fid->i32.ino = inode->i_ino; |
334 | fid->i32.gen = inode->i_generation; | 333 | fid->i32.gen = inode->i_generation; |
335 | if (connectable && !S_ISDIR(inode->i_mode)) { | 334 | if (parent) { |
336 | struct inode *parent; | ||
337 | |||
338 | spin_lock(&dentry->d_lock); | ||
339 | parent = dentry->d_parent->d_inode; | ||
340 | fid->i32.parent_ino = parent->i_ino; | 335 | fid->i32.parent_ino = parent->i_ino; |
341 | fid->i32.parent_gen = parent->i_generation; | 336 | fid->i32.parent_gen = parent->i_generation; |
342 | spin_unlock(&dentry->d_lock); | ||
343 | len = 4; | 337 | len = 4; |
344 | type = FILEID_INO32_GEN_PARENT; | 338 | type = FILEID_INO32_GEN_PARENT; |
345 | } | 339 | } |
@@ -352,11 +346,22 @@ int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len, | |||
352 | { | 346 | { |
353 | const struct export_operations *nop = dentry->d_sb->s_export_op; | 347 | const struct export_operations *nop = dentry->d_sb->s_export_op; |
354 | int error; | 348 | int error; |
349 | struct dentry *p = NULL; | ||
350 | struct inode *inode = dentry->d_inode, *parent = NULL; | ||
355 | 351 | ||
352 | if (connectable && !S_ISDIR(inode->i_mode)) { | ||
353 | p = dget_parent(dentry); | ||
354 | /* | ||
355 | * note that while p might've ceased to be our parent already, | ||
356 | * it's still pinned by and still positive. | ||
357 | */ | ||
358 | parent = p->d_inode; | ||
359 | } | ||
356 | if (nop->encode_fh) | 360 | if (nop->encode_fh) |
357 | error = nop->encode_fh(dentry, fid->raw, max_len, connectable); | 361 | error = nop->encode_fh(inode, fid->raw, max_len, parent); |
358 | else | 362 | else |
359 | error = export_encode_fh(dentry, fid, max_len, connectable); | 363 | error = export_encode_fh(inode, fid, max_len, parent); |
364 | dput(p); | ||
360 | 365 | ||
361 | return error; | 366 | return error; |
362 | } | 367 | } |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index c2973ea5df9a..a3d81ebf6d86 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -735,10 +735,9 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb, | |||
735 | } | 735 | } |
736 | 736 | ||
737 | static int | 737 | static int |
738 | fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) | 738 | fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent) |
739 | { | 739 | { |
740 | int len = *lenp; | 740 | int len = *lenp; |
741 | struct inode *inode = de->d_inode; | ||
742 | u32 ipos_h, ipos_m, ipos_l; | 741 | u32 ipos_h, ipos_m, ipos_l; |
743 | 742 | ||
744 | if (len < 5) { | 743 | if (len < 5) { |
@@ -754,9 +753,9 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) | |||
754 | fh[1] = inode->i_generation; | 753 | fh[1] = inode->i_generation; |
755 | fh[2] = ipos_h; | 754 | fh[2] = ipos_h; |
756 | fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; | 755 | fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; |
757 | spin_lock(&de->d_lock); | 756 | fh[4] = ipos_l; |
758 | fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart; | 757 | if (parent) |
759 | spin_unlock(&de->d_lock); | 758 | fh[4] |= MSDOS_I(parent)->i_logstart; |
760 | return 3; | 759 | return 3; |
761 | } | 760 | } |
762 | 761 | ||
diff --git a/fs/fcntl.c b/fs/fcntl.c index d078b75572a7..81b70e665bf0 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -442,28 +442,24 @@ static int check_fcntl_cmd(unsigned cmd) | |||
442 | SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) | 442 | SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) |
443 | { | 443 | { |
444 | struct file *filp; | 444 | struct file *filp; |
445 | int fput_needed; | ||
445 | long err = -EBADF; | 446 | long err = -EBADF; |
446 | 447 | ||
447 | filp = fget_raw(fd); | 448 | filp = fget_raw_light(fd, &fput_needed); |
448 | if (!filp) | 449 | if (!filp) |
449 | goto out; | 450 | goto out; |
450 | 451 | ||
451 | if (unlikely(filp->f_mode & FMODE_PATH)) { | 452 | if (unlikely(filp->f_mode & FMODE_PATH)) { |
452 | if (!check_fcntl_cmd(cmd)) { | 453 | if (!check_fcntl_cmd(cmd)) |
453 | fput(filp); | 454 | goto out1; |
454 | goto out; | ||
455 | } | ||
456 | } | 455 | } |
457 | 456 | ||
458 | err = security_file_fcntl(filp, cmd, arg); | 457 | err = security_file_fcntl(filp, cmd, arg); |
459 | if (err) { | 458 | if (!err) |
460 | fput(filp); | 459 | err = do_fcntl(fd, cmd, arg, filp); |
461 | return err; | ||
462 | } | ||
463 | 460 | ||
464 | err = do_fcntl(fd, cmd, arg, filp); | 461 | out1: |
465 | 462 | fput_light(filp, fput_needed); | |
466 | fput(filp); | ||
467 | out: | 463 | out: |
468 | return err; | 464 | return err; |
469 | } | 465 | } |
@@ -473,26 +469,21 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | |||
473 | unsigned long, arg) | 469 | unsigned long, arg) |
474 | { | 470 | { |
475 | struct file * filp; | 471 | struct file * filp; |
476 | long err; | 472 | long err = -EBADF; |
473 | int fput_needed; | ||
477 | 474 | ||
478 | err = -EBADF; | 475 | filp = fget_raw_light(fd, &fput_needed); |
479 | filp = fget_raw(fd); | ||
480 | if (!filp) | 476 | if (!filp) |
481 | goto out; | 477 | goto out; |
482 | 478 | ||
483 | if (unlikely(filp->f_mode & FMODE_PATH)) { | 479 | if (unlikely(filp->f_mode & FMODE_PATH)) { |
484 | if (!check_fcntl_cmd(cmd)) { | 480 | if (!check_fcntl_cmd(cmd)) |
485 | fput(filp); | 481 | goto out1; |
486 | goto out; | ||
487 | } | ||
488 | } | 482 | } |
489 | 483 | ||
490 | err = security_file_fcntl(filp, cmd, arg); | 484 | err = security_file_fcntl(filp, cmd, arg); |
491 | if (err) { | 485 | if (err) |
492 | fput(filp); | 486 | goto out1; |
493 | return err; | ||
494 | } | ||
495 | err = -EBADF; | ||
496 | 487 | ||
497 | switch (cmd) { | 488 | switch (cmd) { |
498 | case F_GETLK64: | 489 | case F_GETLK64: |
@@ -507,7 +498,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | |||
507 | err = do_fcntl(fd, cmd, arg, filp); | 498 | err = do_fcntl(fd, cmd, arg, filp); |
508 | break; | 499 | break; |
509 | } | 500 | } |
510 | fput(filp); | 501 | out1: |
502 | fput_light(filp, fput_needed); | ||
511 | out: | 503 | out: |
512 | return err; | 504 | return err; |
513 | } | 505 | } |
diff --git a/fs/file_table.c b/fs/file_table.c index 70f2a0fd6aec..a305d9e2d1b2 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -34,7 +34,6 @@ struct files_stat_struct files_stat = { | |||
34 | .max_files = NR_FILE | 34 | .max_files = NR_FILE |
35 | }; | 35 | }; |
36 | 36 | ||
37 | DECLARE_LGLOCK(files_lglock); | ||
38 | DEFINE_LGLOCK(files_lglock); | 37 | DEFINE_LGLOCK(files_lglock); |
39 | 38 | ||
40 | /* SLAB cache for file structures */ | 39 | /* SLAB cache for file structures */ |
@@ -421,9 +420,9 @@ static inline void __file_sb_list_add(struct file *file, struct super_block *sb) | |||
421 | */ | 420 | */ |
422 | void file_sb_list_add(struct file *file, struct super_block *sb) | 421 | void file_sb_list_add(struct file *file, struct super_block *sb) |
423 | { | 422 | { |
424 | lg_local_lock(files_lglock); | 423 | lg_local_lock(&files_lglock); |
425 | __file_sb_list_add(file, sb); | 424 | __file_sb_list_add(file, sb); |
426 | lg_local_unlock(files_lglock); | 425 | lg_local_unlock(&files_lglock); |
427 | } | 426 | } |
428 | 427 | ||
429 | /** | 428 | /** |
@@ -436,9 +435,9 @@ void file_sb_list_add(struct file *file, struct super_block *sb) | |||
436 | void file_sb_list_del(struct file *file) | 435 | void file_sb_list_del(struct file *file) |
437 | { | 436 | { |
438 | if (!list_empty(&file->f_u.fu_list)) { | 437 | if (!list_empty(&file->f_u.fu_list)) { |
439 | lg_local_lock_cpu(files_lglock, file_list_cpu(file)); | 438 | lg_local_lock_cpu(&files_lglock, file_list_cpu(file)); |
440 | list_del_init(&file->f_u.fu_list); | 439 | list_del_init(&file->f_u.fu_list); |
441 | lg_local_unlock_cpu(files_lglock, file_list_cpu(file)); | 440 | lg_local_unlock_cpu(&files_lglock, file_list_cpu(file)); |
442 | } | 441 | } |
443 | } | 442 | } |
444 | 443 | ||
@@ -485,7 +484,7 @@ void mark_files_ro(struct super_block *sb) | |||
485 | struct file *f; | 484 | struct file *f; |
486 | 485 | ||
487 | retry: | 486 | retry: |
488 | lg_global_lock(files_lglock); | 487 | lg_global_lock(&files_lglock); |
489 | do_file_list_for_each_entry(sb, f) { | 488 | do_file_list_for_each_entry(sb, f) { |
490 | struct vfsmount *mnt; | 489 | struct vfsmount *mnt; |
491 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) | 490 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) |
@@ -502,12 +501,12 @@ retry: | |||
502 | file_release_write(f); | 501 | file_release_write(f); |
503 | mnt = mntget(f->f_path.mnt); | 502 | mnt = mntget(f->f_path.mnt); |
504 | /* This can sleep, so we can't hold the spinlock. */ | 503 | /* This can sleep, so we can't hold the spinlock. */ |
505 | lg_global_unlock(files_lglock); | 504 | lg_global_unlock(&files_lglock); |
506 | mnt_drop_write(mnt); | 505 | mnt_drop_write(mnt); |
507 | mntput(mnt); | 506 | mntput(mnt); |
508 | goto retry; | 507 | goto retry; |
509 | } while_file_list_for_each_entry; | 508 | } while_file_list_for_each_entry; |
510 | lg_global_unlock(files_lglock); | 509 | lg_global_unlock(&files_lglock); |
511 | } | 510 | } |
512 | 511 | ||
513 | void __init files_init(unsigned long mempages) | 512 | void __init files_init(unsigned long mempages) |
@@ -525,6 +524,6 @@ void __init files_init(unsigned long mempages) | |||
525 | n = (mempages * (PAGE_SIZE / 1024)) / 10; | 524 | n = (mempages * (PAGE_SIZE / 1024)) / 10; |
526 | files_stat.max_files = max_t(unsigned long, n, NR_FILE); | 525 | files_stat.max_files = max_t(unsigned long, n, NR_FILE); |
527 | files_defer_init(); | 526 | files_defer_init(); |
528 | lg_lock_init(files_lglock); | 527 | lg_lock_init(&files_lglock, "files_lglock"); |
529 | percpu_counter_init(&nr_files, 0); | 528 | percpu_counter_init(&nr_files, 0); |
530 | } | 529 | } |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 504e61b7fd75..9562109d3a87 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -962,7 +962,9 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
962 | if (err) | 962 | if (err) |
963 | goto out; | 963 | goto out; |
964 | 964 | ||
965 | file_update_time(file); | 965 | err = file_update_time(file); |
966 | if (err) | ||
967 | goto out; | ||
966 | 968 | ||
967 | if (file->f_flags & O_DIRECT) { | 969 | if (file->f_flags & O_DIRECT) { |
968 | written = generic_file_direct_write(iocb, iov, &nr_segs, | 970 | written = generic_file_direct_write(iocb, iov, &nr_segs, |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 56f6dcf30768..42678a33b7bb 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -627,12 +627,10 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, | |||
627 | return ERR_PTR(err); | 627 | return ERR_PTR(err); |
628 | } | 628 | } |
629 | 629 | ||
630 | static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | 630 | static int fuse_encode_fh(struct inode *inode, u32 *fh, int *max_len, |
631 | int connectable) | 631 | struct inode *parent) |
632 | { | 632 | { |
633 | struct inode *inode = dentry->d_inode; | 633 | int len = parent ? 6 : 3; |
634 | bool encode_parent = connectable && !S_ISDIR(inode->i_mode); | ||
635 | int len = encode_parent ? 6 : 3; | ||
636 | u64 nodeid; | 634 | u64 nodeid; |
637 | u32 generation; | 635 | u32 generation; |
638 | 636 | ||
@@ -648,14 +646,9 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
648 | fh[1] = (u32)(nodeid & 0xffffffff); | 646 | fh[1] = (u32)(nodeid & 0xffffffff); |
649 | fh[2] = generation; | 647 | fh[2] = generation; |
650 | 648 | ||
651 | if (encode_parent) { | 649 | if (parent) { |
652 | struct inode *parent; | ||
653 | |||
654 | spin_lock(&dentry->d_lock); | ||
655 | parent = dentry->d_parent->d_inode; | ||
656 | nodeid = get_fuse_inode(parent)->nodeid; | 650 | nodeid = get_fuse_inode(parent)->nodeid; |
657 | generation = parent->i_generation; | 651 | generation = parent->i_generation; |
658 | spin_unlock(&dentry->d_lock); | ||
659 | 652 | ||
660 | fh[3] = (u32)(nodeid >> 32); | 653 | fh[3] = (u32)(nodeid >> 32); |
661 | fh[4] = (u32)(nodeid & 0xffffffff); | 654 | fh[4] = (u32)(nodeid & 0xffffffff); |
@@ -663,7 +656,7 @@ static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
663 | } | 656 | } |
664 | 657 | ||
665 | *max_len = len; | 658 | *max_len = len; |
666 | return encode_parent ? 0x82 : 0x81; | 659 | return parent ? 0x82 : 0x81; |
667 | } | 660 | } |
668 | 661 | ||
669 | static struct dentry *fuse_fh_to_dentry(struct super_block *sb, | 662 | static struct dentry *fuse_fh_to_dentry(struct super_block *sb, |
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 70ba891654f8..e8ed6d4a6181 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -28,15 +28,14 @@ | |||
28 | #define GFS2_LARGE_FH_SIZE 8 | 28 | #define GFS2_LARGE_FH_SIZE 8 |
29 | #define GFS2_OLD_FH_SIZE 10 | 29 | #define GFS2_OLD_FH_SIZE 10 |
30 | 30 | ||
31 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | 31 | static int gfs2_encode_fh(struct inode *inode, __u32 *p, int *len, |
32 | int connectable) | 32 | struct inode *parent) |
33 | { | 33 | { |
34 | __be32 *fh = (__force __be32 *)p; | 34 | __be32 *fh = (__force __be32 *)p; |
35 | struct inode *inode = dentry->d_inode; | ||
36 | struct super_block *sb = inode->i_sb; | 35 | struct super_block *sb = inode->i_sb; |
37 | struct gfs2_inode *ip = GFS2_I(inode); | 36 | struct gfs2_inode *ip = GFS2_I(inode); |
38 | 37 | ||
39 | if (connectable && (*len < GFS2_LARGE_FH_SIZE)) { | 38 | if (parent && (*len < GFS2_LARGE_FH_SIZE)) { |
40 | *len = GFS2_LARGE_FH_SIZE; | 39 | *len = GFS2_LARGE_FH_SIZE; |
41 | return 255; | 40 | return 255; |
42 | } else if (*len < GFS2_SMALL_FH_SIZE) { | 41 | } else if (*len < GFS2_SMALL_FH_SIZE) { |
@@ -50,14 +49,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
50 | fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); | 49 | fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
51 | *len = GFS2_SMALL_FH_SIZE; | 50 | *len = GFS2_SMALL_FH_SIZE; |
52 | 51 | ||
53 | if (!connectable || inode == sb->s_root->d_inode) | 52 | if (!parent || inode == sb->s_root->d_inode) |
54 | return *len; | 53 | return *len; |
55 | 54 | ||
56 | spin_lock(&dentry->d_lock); | 55 | ip = GFS2_I(parent); |
57 | inode = dentry->d_parent->d_inode; | ||
58 | ip = GFS2_I(inode); | ||
59 | igrab(inode); | ||
60 | spin_unlock(&dentry->d_lock); | ||
61 | 56 | ||
62 | fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); | 57 | fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
63 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); | 58 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
@@ -65,8 +60,6 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
65 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); | 60 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
66 | *len = GFS2_LARGE_FH_SIZE; | 61 | *len = GFS2_LARGE_FH_SIZE; |
67 | 62 | ||
68 | iput(inode); | ||
69 | |||
70 | return *len; | 63 | return *len; |
71 | } | 64 | } |
72 | 65 | ||
diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c index 7a5eb2c718c8..cdb84a838068 100644 --- a/fs/hpfs/alloc.c +++ b/fs/hpfs/alloc.c | |||
@@ -16,9 +16,9 @@ | |||
16 | static int chk_if_allocated(struct super_block *s, secno sec, char *msg) | 16 | static int chk_if_allocated(struct super_block *s, secno sec, char *msg) |
17 | { | 17 | { |
18 | struct quad_buffer_head qbh; | 18 | struct quad_buffer_head qbh; |
19 | u32 *bmp; | 19 | __le32 *bmp; |
20 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail; | 20 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail; |
21 | if ((cpu_to_le32(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) { | 21 | if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) { |
22 | hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec); | 22 | hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec); |
23 | goto fail1; | 23 | goto fail1; |
24 | } | 24 | } |
@@ -62,7 +62,7 @@ int hpfs_chk_sectors(struct super_block *s, secno start, int len, char *msg) | |||
62 | static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigned forward) | 62 | static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigned forward) |
63 | { | 63 | { |
64 | struct quad_buffer_head qbh; | 64 | struct quad_buffer_head qbh; |
65 | unsigned *bmp; | 65 | __le32 *bmp; |
66 | unsigned bs = near & ~0x3fff; | 66 | unsigned bs = near & ~0x3fff; |
67 | unsigned nr = (near & 0x3fff) & ~(n - 1); | 67 | unsigned nr = (near & 0x3fff) & ~(n - 1); |
68 | /*unsigned mnr;*/ | 68 | /*unsigned mnr;*/ |
@@ -236,7 +236,7 @@ static secno alloc_in_dirband(struct super_block *s, secno near) | |||
236 | int hpfs_alloc_if_possible(struct super_block *s, secno sec) | 236 | int hpfs_alloc_if_possible(struct super_block *s, secno sec) |
237 | { | 237 | { |
238 | struct quad_buffer_head qbh; | 238 | struct quad_buffer_head qbh; |
239 | u32 *bmp; | 239 | __le32 *bmp; |
240 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end; | 240 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end; |
241 | if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) { | 241 | if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) { |
242 | bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f))); | 242 | bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f))); |
@@ -254,7 +254,7 @@ int hpfs_alloc_if_possible(struct super_block *s, secno sec) | |||
254 | void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) | 254 | void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) |
255 | { | 255 | { |
256 | struct quad_buffer_head qbh; | 256 | struct quad_buffer_head qbh; |
257 | u32 *bmp; | 257 | __le32 *bmp; |
258 | struct hpfs_sb_info *sbi = hpfs_sb(s); | 258 | struct hpfs_sb_info *sbi = hpfs_sb(s); |
259 | /*printk("2 - ");*/ | 259 | /*printk("2 - ");*/ |
260 | if (!n) return; | 260 | if (!n) return; |
@@ -299,7 +299,7 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) | |||
299 | int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14; | 299 | int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14; |
300 | int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff; | 300 | int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff; |
301 | int i, j; | 301 | int i, j; |
302 | u32 *bmp; | 302 | __le32 *bmp; |
303 | struct quad_buffer_head qbh; | 303 | struct quad_buffer_head qbh; |
304 | if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) { | 304 | if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) { |
305 | for (j = 0; j < 512; j++) { | 305 | for (j = 0; j < 512; j++) { |
@@ -351,7 +351,7 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno) | |||
351 | hpfs_free_sectors(s, dno, 4); | 351 | hpfs_free_sectors(s, dno, 4); |
352 | } else { | 352 | } else { |
353 | struct quad_buffer_head qbh; | 353 | struct quad_buffer_head qbh; |
354 | u32 *bmp; | 354 | __le32 *bmp; |
355 | unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4; | 355 | unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4; |
356 | if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { | 356 | if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { |
357 | return; | 357 | return; |
diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c index 08b503e8ed29..4bae4a4a60b1 100644 --- a/fs/hpfs/anode.c +++ b/fs/hpfs/anode.c | |||
@@ -20,7 +20,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, | |||
20 | int c1, c2 = 0; | 20 | int c1, c2 = 0; |
21 | go_down: | 21 | go_down: |
22 | if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; | 22 | if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; |
23 | if (btree->internal) { | 23 | if (bp_internal(btree)) { |
24 | for (i = 0; i < btree->n_used_nodes; i++) | 24 | for (i = 0; i < btree->n_used_nodes; i++) |
25 | if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { | 25 | if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { |
26 | a = le32_to_cpu(btree->u.internal[i].down); | 26 | a = le32_to_cpu(btree->u.internal[i].down); |
@@ -82,7 +82,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
82 | brelse(bh); | 82 | brelse(bh); |
83 | return -1; | 83 | return -1; |
84 | } | 84 | } |
85 | if (btree->internal) { | 85 | if (bp_internal(btree)) { |
86 | a = le32_to_cpu(btree->u.internal[n].down); | 86 | a = le32_to_cpu(btree->u.internal[n].down); |
87 | btree->u.internal[n].file_secno = cpu_to_le32(-1); | 87 | btree->u.internal[n].file_secno = cpu_to_le32(-1); |
88 | mark_buffer_dirty(bh); | 88 | mark_buffer_dirty(bh); |
@@ -129,12 +129,12 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
129 | } | 129 | } |
130 | if (a == node && fnod) { | 130 | if (a == node && fnod) { |
131 | anode->up = cpu_to_le32(node); | 131 | anode->up = cpu_to_le32(node); |
132 | anode->btree.fnode_parent = 1; | 132 | anode->btree.flags |= BP_fnode_parent; |
133 | anode->btree.n_used_nodes = btree->n_used_nodes; | 133 | anode->btree.n_used_nodes = btree->n_used_nodes; |
134 | anode->btree.first_free = btree->first_free; | 134 | anode->btree.first_free = btree->first_free; |
135 | anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes; | 135 | anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes; |
136 | memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12); | 136 | memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12); |
137 | btree->internal = 1; | 137 | btree->flags |= BP_internal; |
138 | btree->n_free_nodes = 11; | 138 | btree->n_free_nodes = 11; |
139 | btree->n_used_nodes = 1; | 139 | btree->n_used_nodes = 1; |
140 | btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); | 140 | btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); |
@@ -184,7 +184,10 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
184 | hpfs_free_sectors(s, ra, 1); | 184 | hpfs_free_sectors(s, ra, 1); |
185 | if ((anode = hpfs_map_anode(s, na, &bh))) { | 185 | if ((anode = hpfs_map_anode(s, na, &bh))) { |
186 | anode->up = cpu_to_le32(up); | 186 | anode->up = cpu_to_le32(up); |
187 | anode->btree.fnode_parent = up == node && fnod; | 187 | if (up == node && fnod) |
188 | anode->btree.flags |= BP_fnode_parent; | ||
189 | else | ||
190 | anode->btree.flags &= ~BP_fnode_parent; | ||
188 | mark_buffer_dirty(bh); | 191 | mark_buffer_dirty(bh); |
189 | brelse(bh); | 192 | brelse(bh); |
190 | } | 193 | } |
@@ -198,7 +201,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
198 | if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { | 201 | if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { |
199 | anode = new_anode; | 202 | anode = new_anode; |
200 | /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/ | 203 | /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/ |
201 | anode->btree.internal = 1; | 204 | anode->btree.flags |= BP_internal; |
202 | anode->btree.n_used_nodes = 1; | 205 | anode->btree.n_used_nodes = 1; |
203 | anode->btree.n_free_nodes = 59; | 206 | anode->btree.n_free_nodes = 59; |
204 | anode->btree.first_free = cpu_to_le16(16); | 207 | anode->btree.first_free = cpu_to_le16(16); |
@@ -215,7 +218,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
215 | } | 218 | } |
216 | if ((anode = hpfs_map_anode(s, na, &bh))) { | 219 | if ((anode = hpfs_map_anode(s, na, &bh))) { |
217 | anode->up = cpu_to_le32(node); | 220 | anode->up = cpu_to_le32(node); |
218 | if (fnod) anode->btree.fnode_parent = 1; | 221 | if (fnod) |
222 | anode->btree.flags |= BP_fnode_parent; | ||
219 | mark_buffer_dirty(bh); | 223 | mark_buffer_dirty(bh); |
220 | brelse(bh); | 224 | brelse(bh); |
221 | } | 225 | } |
@@ -234,18 +238,19 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
234 | } | 238 | } |
235 | ranode->up = cpu_to_le32(node); | 239 | ranode->up = cpu_to_le32(node); |
236 | memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); | 240 | memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); |
237 | if (fnod) ranode->btree.fnode_parent = 1; | 241 | if (fnod) |
238 | ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes; | 242 | ranode->btree.flags |= BP_fnode_parent; |
239 | if (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) { | 243 | ranode->btree.n_free_nodes = (bp_internal(&ranode->btree) ? 60 : 40) - ranode->btree.n_used_nodes; |
244 | if (bp_internal(&ranode->btree)) for (n = 0; n < ranode->btree.n_used_nodes; n++) { | ||
240 | struct anode *unode; | 245 | struct anode *unode; |
241 | if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { | 246 | if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { |
242 | unode->up = cpu_to_le32(ra); | 247 | unode->up = cpu_to_le32(ra); |
243 | unode->btree.fnode_parent = 0; | 248 | unode->btree.flags &= ~BP_fnode_parent; |
244 | mark_buffer_dirty(bh1); | 249 | mark_buffer_dirty(bh1); |
245 | brelse(bh1); | 250 | brelse(bh1); |
246 | } | 251 | } |
247 | } | 252 | } |
248 | btree->internal = 1; | 253 | btree->flags |= BP_internal; |
249 | btree->n_free_nodes = fnod ? 10 : 58; | 254 | btree->n_free_nodes = fnod ? 10 : 58; |
250 | btree->n_used_nodes = 2; | 255 | btree->n_used_nodes = 2; |
251 | btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree); | 256 | btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree); |
@@ -278,7 +283,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) | |||
278 | int d1, d2; | 283 | int d1, d2; |
279 | go_down: | 284 | go_down: |
280 | d2 = 0; | 285 | d2 = 0; |
281 | while (btree1->internal) { | 286 | while (bp_internal(btree1)) { |
282 | ano = le32_to_cpu(btree1->u.internal[pos].down); | 287 | ano = le32_to_cpu(btree1->u.internal[pos].down); |
283 | if (level) brelse(bh); | 288 | if (level) brelse(bh); |
284 | if (hpfs_sb(s)->sb_chk) | 289 | if (hpfs_sb(s)->sb_chk) |
@@ -412,13 +417,13 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) | |||
412 | btree->n_free_nodes = 8; | 417 | btree->n_free_nodes = 8; |
413 | btree->n_used_nodes = 0; | 418 | btree->n_used_nodes = 0; |
414 | btree->first_free = cpu_to_le16(8); | 419 | btree->first_free = cpu_to_le16(8); |
415 | btree->internal = 0; | 420 | btree->flags &= ~BP_internal; |
416 | mark_buffer_dirty(bh); | 421 | mark_buffer_dirty(bh); |
417 | } else hpfs_free_sectors(s, f, 1); | 422 | } else hpfs_free_sectors(s, f, 1); |
418 | brelse(bh); | 423 | brelse(bh); |
419 | return; | 424 | return; |
420 | } | 425 | } |
421 | while (btree->internal) { | 426 | while (bp_internal(btree)) { |
422 | nodes = btree->n_used_nodes + btree->n_free_nodes; | 427 | nodes = btree->n_used_nodes + btree->n_free_nodes; |
423 | for (i = 0; i < btree->n_used_nodes; i++) | 428 | for (i = 0; i < btree->n_used_nodes; i++) |
424 | if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f; | 429 | if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f; |
@@ -479,13 +484,13 @@ void hpfs_remove_fnode(struct super_block *s, fnode_secno fno) | |||
479 | struct extended_attribute *ea; | 484 | struct extended_attribute *ea; |
480 | struct extended_attribute *ea_end; | 485 | struct extended_attribute *ea_end; |
481 | if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return; | 486 | if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return; |
482 | if (!fnode->dirflag) hpfs_remove_btree(s, &fnode->btree); | 487 | if (!fnode_is_dir(fnode)) hpfs_remove_btree(s, &fnode->btree); |
483 | else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno)); | 488 | else hpfs_remove_dtree(s, le32_to_cpu(fnode->u.external[0].disk_secno)); |
484 | ea_end = fnode_end_ea(fnode); | 489 | ea_end = fnode_end_ea(fnode); |
485 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) | 490 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) |
486 | if (ea->indirect) | 491 | if (ea_indirect(ea)) |
487 | hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); | 492 | hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea)); |
488 | hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l)); | 493 | hpfs_ea_ext_remove(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l)); |
489 | brelse(bh); | 494 | brelse(bh); |
490 | hpfs_free_sectors(s, fno, 1); | 495 | hpfs_free_sectors(s, fno, 1); |
491 | } | 496 | } |
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 2fa0089a02a8..b8472f803f4e 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -87,7 +87,7 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
87 | ret = -EIOERROR; | 87 | ret = -EIOERROR; |
88 | goto out; | 88 | goto out; |
89 | } | 89 | } |
90 | if (!fno->dirflag) { | 90 | if (!fnode_is_dir(fno)) { |
91 | e = 1; | 91 | e = 1; |
92 | hpfs_error(inode->i_sb, "not a directory, fnode %08lx", | 92 | hpfs_error(inode->i_sb, "not a directory, fnode %08lx", |
93 | (unsigned long)inode->i_ino); | 93 | (unsigned long)inode->i_ino); |
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 1e0e2ac30fd3..3228c524ebe5 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c | |||
@@ -153,7 +153,7 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno | |||
153 | } | 153 | } |
154 | de->length = cpu_to_le16(36); | 154 | de->length = cpu_to_le16(36); |
155 | de->down = 1; | 155 | de->down = 1; |
156 | *(dnode_secno *)((char *)de + 32) = cpu_to_le32(ptr); | 156 | *(__le32 *)((char *)de + 32) = cpu_to_le32(ptr); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
@@ -177,7 +177,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, | |||
177 | memmove((char *)de + d_size, de, (char *)de_end - (char *)de); | 177 | memmove((char *)de + d_size, de, (char *)de_end - (char *)de); |
178 | memset(de, 0, d_size); | 178 | memset(de, 0, d_size); |
179 | if (down_ptr) { | 179 | if (down_ptr) { |
180 | *(dnode_secno *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr); | 180 | *(__le32 *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr); |
181 | de->down = 1; | 181 | de->down = 1; |
182 | } | 182 | } |
183 | de->length = cpu_to_le16(d_size); | 183 | de->length = cpu_to_le16(d_size); |
@@ -656,7 +656,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
656 | del->down = 0; | 656 | del->down = 0; |
657 | d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4); | 657 | d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4); |
658 | } else if (down) | 658 | } else if (down) |
659 | *(dnode_secno *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down); | 659 | *(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down); |
660 | } else goto endm; | 660 | } else goto endm; |
661 | if (!(de_cp = kmalloc(le16_to_cpu(de_prev->length), GFP_NOFS))) { | 661 | if (!(de_cp = kmalloc(le16_to_cpu(de_prev->length), GFP_NOFS))) { |
662 | printk("HPFS: out of memory for dtree balancing\n"); | 662 | printk("HPFS: out of memory for dtree balancing\n"); |
@@ -672,7 +672,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
672 | de_prev->down = 1; | 672 | de_prev->down = 1; |
673 | dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4); | 673 | dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4); |
674 | } | 674 | } |
675 | *(dnode_secno *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown); | 675 | *(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown); |
676 | hpfs_mark_4buffers_dirty(&qbh); | 676 | hpfs_mark_4buffers_dirty(&qbh); |
677 | hpfs_brelse4(&qbh); | 677 | hpfs_brelse4(&qbh); |
678 | for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4); | 678 | for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4); |
@@ -1015,7 +1015,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno, | |||
1015 | kfree(name2); | 1015 | kfree(name2); |
1016 | return NULL; | 1016 | return NULL; |
1017 | } | 1017 | } |
1018 | if (!upf->dirflag) { | 1018 | if (!fnode_is_dir(upf)) { |
1019 | brelse(bh); | 1019 | brelse(bh); |
1020 | hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, le32_to_cpu(f->up)); | 1020 | hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, le32_to_cpu(f->up)); |
1021 | kfree(name2); | 1021 | kfree(name2); |
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index d8b84d113c89..bcaafcd2666a 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c | |||
@@ -23,15 +23,15 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len) | |||
23 | return; | 23 | return; |
24 | } | 24 | } |
25 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; | 25 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; |
26 | if (ea->indirect) { | 26 | if (ea_indirect(ea)) { |
27 | if (ea_valuelen(ea) != 8) { | 27 | if (ea_valuelen(ea) != 8) { |
28 | hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x", | 28 | hpfs_error(s, "ea_indirect(ea) set while ea->valuelen!=8, %s %08x, pos %08x", |
29 | ano ? "anode" : "sectors", a, pos); | 29 | ano ? "anode" : "sectors", a, pos); |
30 | return; | 30 | return; |
31 | } | 31 | } |
32 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4)) | 32 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4)) |
33 | return; | 33 | return; |
34 | hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea)); | 34 | hpfs_ea_remove(s, ea_sec(ea), ea_in_anode(ea), ea_len(ea)); |
35 | } | 35 | } |
36 | pos += ea->namelen + ea_valuelen(ea) + 5; | 36 | pos += ea->namelen + ea_valuelen(ea) + 5; |
37 | } | 37 | } |
@@ -81,7 +81,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
81 | struct extended_attribute *ea_end = fnode_end_ea(fnode); | 81 | struct extended_attribute *ea_end = fnode_end_ea(fnode); |
82 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) | 82 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) |
83 | if (!strcmp(ea->name, key)) { | 83 | if (!strcmp(ea->name, key)) { |
84 | if (ea->indirect) | 84 | if (ea_indirect(ea)) |
85 | goto indirect; | 85 | goto indirect; |
86 | if (ea_valuelen(ea) >= size) | 86 | if (ea_valuelen(ea) >= size) |
87 | return -EINVAL; | 87 | return -EINVAL; |
@@ -91,7 +91,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
91 | } | 91 | } |
92 | a = le32_to_cpu(fnode->ea_secno); | 92 | a = le32_to_cpu(fnode->ea_secno); |
93 | len = le32_to_cpu(fnode->ea_size_l); | 93 | len = le32_to_cpu(fnode->ea_size_l); |
94 | ano = fnode->ea_anode; | 94 | ano = fnode_in_anode(fnode); |
95 | pos = 0; | 95 | pos = 0; |
96 | while (pos < len) { | 96 | while (pos < len) { |
97 | ea = (struct extended_attribute *)ex; | 97 | ea = (struct extended_attribute *)ex; |
@@ -101,10 +101,10 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
101 | return -EIO; | 101 | return -EIO; |
102 | } | 102 | } |
103 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO; | 103 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO; |
104 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) | 104 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4)) |
105 | return -EIO; | 105 | return -EIO; |
106 | if (!strcmp(ea->name, key)) { | 106 | if (!strcmp(ea->name, key)) { |
107 | if (ea->indirect) | 107 | if (ea_indirect(ea)) |
108 | goto indirect; | 108 | goto indirect; |
109 | if (ea_valuelen(ea) >= size) | 109 | if (ea_valuelen(ea) >= size) |
110 | return -EINVAL; | 110 | return -EINVAL; |
@@ -119,7 +119,7 @@ int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, | |||
119 | indirect: | 119 | indirect: |
120 | if (ea_len(ea) >= size) | 120 | if (ea_len(ea) >= size) |
121 | return -EINVAL; | 121 | return -EINVAL; |
122 | if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf)) | 122 | if (hpfs_ea_read(s, ea_sec(ea), ea_in_anode(ea), 0, ea_len(ea), buf)) |
123 | return -EIO; | 123 | return -EIO; |
124 | buf[ea_len(ea)] = 0; | 124 | buf[ea_len(ea)] = 0; |
125 | return 0; | 125 | return 0; |
@@ -136,8 +136,8 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si | |||
136 | struct extended_attribute *ea_end = fnode_end_ea(fnode); | 136 | struct extended_attribute *ea_end = fnode_end_ea(fnode); |
137 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) | 137 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) |
138 | if (!strcmp(ea->name, key)) { | 138 | if (!strcmp(ea->name, key)) { |
139 | if (ea->indirect) | 139 | if (ea_indirect(ea)) |
140 | return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); | 140 | return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea)); |
141 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { | 141 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { |
142 | printk("HPFS: out of memory for EA\n"); | 142 | printk("HPFS: out of memory for EA\n"); |
143 | return NULL; | 143 | return NULL; |
@@ -148,7 +148,7 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si | |||
148 | } | 148 | } |
149 | a = le32_to_cpu(fnode->ea_secno); | 149 | a = le32_to_cpu(fnode->ea_secno); |
150 | len = le32_to_cpu(fnode->ea_size_l); | 150 | len = le32_to_cpu(fnode->ea_size_l); |
151 | ano = fnode->ea_anode; | 151 | ano = fnode_in_anode(fnode); |
152 | pos = 0; | 152 | pos = 0; |
153 | while (pos < len) { | 153 | while (pos < len) { |
154 | char ex[4 + 255 + 1 + 8]; | 154 | char ex[4 + 255 + 1 + 8]; |
@@ -159,11 +159,11 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si | |||
159 | return NULL; | 159 | return NULL; |
160 | } | 160 | } |
161 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL; | 161 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL; |
162 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) | 162 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4)) |
163 | return NULL; | 163 | return NULL; |
164 | if (!strcmp(ea->name, key)) { | 164 | if (!strcmp(ea->name, key)) { |
165 | if (ea->indirect) | 165 | if (ea_indirect(ea)) |
166 | return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea)); | 166 | return get_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), *size = ea_len(ea)); |
167 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { | 167 | if (!(ret = kmalloc((*size = ea_valuelen(ea)) + 1, GFP_NOFS))) { |
168 | printk("HPFS: out of memory for EA\n"); | 168 | printk("HPFS: out of memory for EA\n"); |
169 | return NULL; | 169 | return NULL; |
@@ -199,9 +199,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
199 | struct extended_attribute *ea_end = fnode_end_ea(fnode); | 199 | struct extended_attribute *ea_end = fnode_end_ea(fnode); |
200 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) | 200 | for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) |
201 | if (!strcmp(ea->name, key)) { | 201 | if (!strcmp(ea->name, key)) { |
202 | if (ea->indirect) { | 202 | if (ea_indirect(ea)) { |
203 | if (ea_len(ea) == size) | 203 | if (ea_len(ea) == size) |
204 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); | 204 | set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size); |
205 | } else if (ea_valuelen(ea) == size) { | 205 | } else if (ea_valuelen(ea) == size) { |
206 | memcpy(ea_data(ea), data, size); | 206 | memcpy(ea_data(ea), data, size); |
207 | } | 207 | } |
@@ -209,7 +209,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
209 | } | 209 | } |
210 | a = le32_to_cpu(fnode->ea_secno); | 210 | a = le32_to_cpu(fnode->ea_secno); |
211 | len = le32_to_cpu(fnode->ea_size_l); | 211 | len = le32_to_cpu(fnode->ea_size_l); |
212 | ano = fnode->ea_anode; | 212 | ano = fnode_in_anode(fnode); |
213 | pos = 0; | 213 | pos = 0; |
214 | while (pos < len) { | 214 | while (pos < len) { |
215 | char ex[4 + 255 + 1 + 8]; | 215 | char ex[4 + 255 + 1 + 8]; |
@@ -220,12 +220,12 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
220 | return; | 220 | return; |
221 | } | 221 | } |
222 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; | 222 | if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return; |
223 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) | 223 | if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea_indirect(ea) ? 8 : 0), ex + 4)) |
224 | return; | 224 | return; |
225 | if (!strcmp(ea->name, key)) { | 225 | if (!strcmp(ea->name, key)) { |
226 | if (ea->indirect) { | 226 | if (ea_indirect(ea)) { |
227 | if (ea_len(ea) == size) | 227 | if (ea_len(ea) == size) |
228 | set_indirect_ea(s, ea->anode, ea_sec(ea), data, size); | 228 | set_indirect_ea(s, ea_in_anode(ea), ea_sec(ea), data, size); |
229 | } | 229 | } |
230 | else { | 230 | else { |
231 | if (ea_valuelen(ea) == size) | 231 | if (ea_valuelen(ea) == size) |
@@ -246,7 +246,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
246 | if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) { | 246 | if (le16_to_cpu(fnode->ea_offs) < 0xc4 || le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200) { |
247 | hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", | 247 | hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", |
248 | (unsigned long)inode->i_ino, | 248 | (unsigned long)inode->i_ino, |
249 | le32_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s)); | 249 | le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s)); |
250 | return; | 250 | return; |
251 | } | 251 | } |
252 | if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) && | 252 | if ((le16_to_cpu(fnode->ea_size_s) || !le32_to_cpu(fnode->ea_size_l)) && |
@@ -276,7 +276,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
276 | fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s)); | 276 | fnode->ea_size_l = cpu_to_le32(le16_to_cpu(fnode->ea_size_s)); |
277 | fnode->ea_size_s = cpu_to_le16(0); | 277 | fnode->ea_size_s = cpu_to_le16(0); |
278 | fnode->ea_secno = cpu_to_le32(n); | 278 | fnode->ea_secno = cpu_to_le32(n); |
279 | fnode->ea_anode = cpu_to_le32(0); | 279 | fnode->flags &= ~FNODE_anode; |
280 | mark_buffer_dirty(bh); | 280 | mark_buffer_dirty(bh); |
281 | brelse(bh); | 281 | brelse(bh); |
282 | } | 282 | } |
@@ -288,9 +288,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
288 | secno q = hpfs_alloc_sector(s, fno, 1, 0); | 288 | secno q = hpfs_alloc_sector(s, fno, 1, 0); |
289 | if (!q) goto bail; | 289 | if (!q) goto bail; |
290 | fnode->ea_secno = cpu_to_le32(q); | 290 | fnode->ea_secno = cpu_to_le32(q); |
291 | fnode->ea_anode = 0; | 291 | fnode->flags &= ~FNODE_anode; |
292 | len++; | 292 | len++; |
293 | } else if (!fnode->ea_anode) { | 293 | } else if (!fnode_in_anode(fnode)) { |
294 | if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) { | 294 | if (hpfs_alloc_if_possible(s, le32_to_cpu(fnode->ea_secno) + len)) { |
295 | len++; | 295 | len++; |
296 | } else { | 296 | } else { |
@@ -310,7 +310,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
310 | anode->u.external[0].length = cpu_to_le32(len); | 310 | anode->u.external[0].length = cpu_to_le32(len); |
311 | mark_buffer_dirty(bh); | 311 | mark_buffer_dirty(bh); |
312 | brelse(bh); | 312 | brelse(bh); |
313 | fnode->ea_anode = 1; | 313 | fnode->flags |= FNODE_anode; |
314 | fnode->ea_secno = cpu_to_le32(a_s);*/ | 314 | fnode->ea_secno = cpu_to_le32(a_s);*/ |
315 | secno new_sec; | 315 | secno new_sec; |
316 | int i; | 316 | int i; |
@@ -338,7 +338,7 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
338 | len = (pos + 511) >> 9; | 338 | len = (pos + 511) >> 9; |
339 | } | 339 | } |
340 | } | 340 | } |
341 | if (fnode->ea_anode) { | 341 | if (fnode_in_anode(fnode)) { |
342 | if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno), | 342 | if (hpfs_add_sector_to_btree(s, le32_to_cpu(fnode->ea_secno), |
343 | 0, len) != -1) { | 343 | 0, len) != -1) { |
344 | len++; | 344 | len++; |
@@ -351,16 +351,16 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, const char *key, | |||
351 | h[1] = strlen(key); | 351 | h[1] = strlen(key); |
352 | h[2] = size & 0xff; | 352 | h[2] = size & 0xff; |
353 | h[3] = size >> 8; | 353 | h[3] = size >> 8; |
354 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail; | 354 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l), 4, h)) goto bail; |
355 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail; | 355 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 4, h[1] + 1, key)) goto bail; |
356 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode->ea_anode, le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail; | 356 | if (hpfs_ea_write(s, le32_to_cpu(fnode->ea_secno), fnode_in_anode(fnode), le32_to_cpu(fnode->ea_size_l) + 5 + h[1], size, data)) goto bail; |
357 | fnode->ea_size_l = cpu_to_le32(pos); | 357 | fnode->ea_size_l = cpu_to_le32(pos); |
358 | ret: | 358 | ret: |
359 | hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; | 359 | hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size; |
360 | return; | 360 | return; |
361 | bail: | 361 | bail: |
362 | if (le32_to_cpu(fnode->ea_secno)) | 362 | if (le32_to_cpu(fnode->ea_secno)) |
363 | if (fnode->ea_anode) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9); | 363 | if (fnode_in_anode(fnode)) hpfs_truncate_btree(s, le32_to_cpu(fnode->ea_secno), 1, (le32_to_cpu(fnode->ea_size_l) + 511) >> 9); |
364 | else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9)); | 364 | else hpfs_free_sectors(s, le32_to_cpu(fnode->ea_secno) + ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9), len - ((le32_to_cpu(fnode->ea_size_l) + 511) >> 9)); |
365 | else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0); | 365 | else fnode->ea_secno = fnode->ea_size_l = cpu_to_le32(0); |
366 | } | 366 | } |
diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h index 8b0650aae328..cce025aff1b1 100644 --- a/fs/hpfs/hpfs.h +++ b/fs/hpfs/hpfs.h | |||
@@ -51,11 +51,11 @@ struct hpfs_boot_block | |||
51 | u8 n_rootdir_entries[2]; | 51 | u8 n_rootdir_entries[2]; |
52 | u8 n_sectors_s[2]; | 52 | u8 n_sectors_s[2]; |
53 | u8 media_byte; | 53 | u8 media_byte; |
54 | u16 sectors_per_fat; | 54 | __le16 sectors_per_fat; |
55 | u16 sectors_per_track; | 55 | __le16 sectors_per_track; |
56 | u16 heads_per_cyl; | 56 | __le16 heads_per_cyl; |
57 | u32 n_hidden_sectors; | 57 | __le32 n_hidden_sectors; |
58 | u32 n_sectors_l; /* size of partition */ | 58 | __le32 n_sectors_l; /* size of partition */ |
59 | u8 drive_number; | 59 | u8 drive_number; |
60 | u8 mbz; | 60 | u8 mbz; |
61 | u8 sig_28h; /* 28h */ | 61 | u8 sig_28h; /* 28h */ |
@@ -63,7 +63,7 @@ struct hpfs_boot_block | |||
63 | u8 vol_label[11]; | 63 | u8 vol_label[11]; |
64 | u8 sig_hpfs[8]; /* "HPFS " */ | 64 | u8 sig_hpfs[8]; /* "HPFS " */ |
65 | u8 pad[448]; | 65 | u8 pad[448]; |
66 | u16 magic; /* aa55 */ | 66 | __le16 magic; /* aa55 */ |
67 | }; | 67 | }; |
68 | 68 | ||
69 | 69 | ||
@@ -75,28 +75,28 @@ struct hpfs_boot_block | |||
75 | 75 | ||
76 | struct hpfs_super_block | 76 | struct hpfs_super_block |
77 | { | 77 | { |
78 | u32 magic; /* f995 e849 */ | 78 | __le32 magic; /* f995 e849 */ |
79 | u32 magic1; /* fa53 e9c5, more magic? */ | 79 | __le32 magic1; /* fa53 e9c5, more magic? */ |
80 | u8 version; /* version of a filesystem usually 2 */ | 80 | u8 version; /* version of a filesystem usually 2 */ |
81 | u8 funcversion; /* functional version - oldest version | 81 | u8 funcversion; /* functional version - oldest version |
82 | of filesystem that can understand | 82 | of filesystem that can understand |
83 | this disk */ | 83 | this disk */ |
84 | u16 zero; /* 0 */ | 84 | __le16 zero; /* 0 */ |
85 | fnode_secno root; /* fnode of root directory */ | 85 | __le32 root; /* fnode of root directory */ |
86 | secno n_sectors; /* size of filesystem */ | 86 | __le32 n_sectors; /* size of filesystem */ |
87 | u32 n_badblocks; /* number of bad blocks */ | 87 | __le32 n_badblocks; /* number of bad blocks */ |
88 | secno bitmaps; /* pointers to free space bit maps */ | 88 | __le32 bitmaps; /* pointers to free space bit maps */ |
89 | u32 zero1; /* 0 */ | 89 | __le32 zero1; /* 0 */ |
90 | secno badblocks; /* bad block list */ | 90 | __le32 badblocks; /* bad block list */ |
91 | u32 zero3; /* 0 */ | 91 | __le32 zero3; /* 0 */ |
92 | time32_t last_chkdsk; /* date last checked, 0 if never */ | 92 | __le32 last_chkdsk; /* date last checked, 0 if never */ |
93 | time32_t last_optimize; /* date last optimized, 0 if never */ | 93 | __le32 last_optimize; /* date last optimized, 0 if never */ |
94 | secno n_dir_band; /* number of sectors in dir band */ | 94 | __le32 n_dir_band; /* number of sectors in dir band */ |
95 | secno dir_band_start; /* first sector in dir band */ | 95 | __le32 dir_band_start; /* first sector in dir band */ |
96 | secno dir_band_end; /* last sector in dir band */ | 96 | __le32 dir_band_end; /* last sector in dir band */ |
97 | secno dir_band_bitmap; /* free space map, 1 dnode per bit */ | 97 | __le32 dir_band_bitmap; /* free space map, 1 dnode per bit */ |
98 | u8 volume_name[32]; /* not used */ | 98 | u8 volume_name[32]; /* not used */ |
99 | secno user_id_table; /* 8 preallocated sectors - user id */ | 99 | __le32 user_id_table; /* 8 preallocated sectors - user id */ |
100 | u32 zero6[103]; /* 0 */ | 100 | u32 zero6[103]; /* 0 */ |
101 | }; | 101 | }; |
102 | 102 | ||
@@ -109,8 +109,8 @@ struct hpfs_super_block | |||
109 | 109 | ||
110 | struct hpfs_spare_block | 110 | struct hpfs_spare_block |
111 | { | 111 | { |
112 | u32 magic; /* f991 1849 */ | 112 | __le32 magic; /* f991 1849 */ |
113 | u32 magic1; /* fa52 29c5, more magic? */ | 113 | __le32 magic1; /* fa52 29c5, more magic? */ |
114 | 114 | ||
115 | #ifdef __LITTLE_ENDIAN | 115 | #ifdef __LITTLE_ENDIAN |
116 | u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */ | 116 | u8 dirty: 1; /* 0 clean, 1 "improperly stopped" */ |
@@ -153,21 +153,21 @@ struct hpfs_spare_block | |||
153 | u8 mm_contlgulty; | 153 | u8 mm_contlgulty; |
154 | u8 unused; | 154 | u8 unused; |
155 | 155 | ||
156 | secno hotfix_map; /* info about remapped bad sectors */ | 156 | __le32 hotfix_map; /* info about remapped bad sectors */ |
157 | u32 n_spares_used; /* number of hotfixes */ | 157 | __le32 n_spares_used; /* number of hotfixes */ |
158 | u32 n_spares; /* number of spares in hotfix map */ | 158 | __le32 n_spares; /* number of spares in hotfix map */ |
159 | u32 n_dnode_spares_free; /* spare dnodes unused */ | 159 | __le32 n_dnode_spares_free; /* spare dnodes unused */ |
160 | u32 n_dnode_spares; /* length of spare_dnodes[] list, | 160 | __le32 n_dnode_spares; /* length of spare_dnodes[] list, |
161 | follows in this block*/ | 161 | follows in this block*/ |
162 | secno code_page_dir; /* code page directory block */ | 162 | __le32 code_page_dir; /* code page directory block */ |
163 | u32 n_code_pages; /* number of code pages */ | 163 | __le32 n_code_pages; /* number of code pages */ |
164 | u32 super_crc; /* on HPFS386 and LAN Server this is | 164 | __le32 super_crc; /* on HPFS386 and LAN Server this is |
165 | checksum of superblock, on normal | 165 | checksum of superblock, on normal |
166 | OS/2 unused */ | 166 | OS/2 unused */ |
167 | u32 spare_crc; /* on HPFS386 checksum of spareblock */ | 167 | __le32 spare_crc; /* on HPFS386 checksum of spareblock */ |
168 | u32 zero1[15]; /* unused */ | 168 | __le32 zero1[15]; /* unused */ |
169 | dnode_secno spare_dnodes[100]; /* emergency free dnode list */ | 169 | __le32 spare_dnodes[100]; /* emergency free dnode list */ |
170 | u32 zero2[1]; /* room for more? */ | 170 | __le32 zero2[1]; /* room for more? */ |
171 | }; | 171 | }; |
172 | 172 | ||
173 | /* The bad block list is 4 sectors long. The first word must be zero, | 173 | /* The bad block list is 4 sectors long. The first word must be zero, |
@@ -202,18 +202,18 @@ struct hpfs_spare_block | |||
202 | 202 | ||
203 | struct code_page_directory | 203 | struct code_page_directory |
204 | { | 204 | { |
205 | u32 magic; /* 4945 21f7 */ | 205 | __le32 magic; /* 4945 21f7 */ |
206 | u32 n_code_pages; /* number of pointers following */ | 206 | __le32 n_code_pages; /* number of pointers following */ |
207 | u32 zero1[2]; | 207 | __le32 zero1[2]; |
208 | struct { | 208 | struct { |
209 | u16 ix; /* index */ | 209 | __le16 ix; /* index */ |
210 | u16 code_page_number; /* code page number */ | 210 | __le16 code_page_number; /* code page number */ |
211 | u32 bounds; /* matches corresponding word | 211 | __le32 bounds; /* matches corresponding word |
212 | in data block */ | 212 | in data block */ |
213 | secno code_page_data; /* sector number of a code_page_data | 213 | __le32 code_page_data; /* sector number of a code_page_data |
214 | containing c.p. array */ | 214 | containing c.p. array */ |
215 | u16 index; /* index in c.p. array in that sector*/ | 215 | __le16 index; /* index in c.p. array in that sector*/ |
216 | u16 unknown; /* some unknown value; usually 0; | 216 | __le16 unknown; /* some unknown value; usually 0; |
217 | 2 in Japanese version */ | 217 | 2 in Japanese version */ |
218 | } array[31]; /* unknown length */ | 218 | } array[31]; /* unknown length */ |
219 | }; | 219 | }; |
@@ -224,19 +224,19 @@ struct code_page_directory | |||
224 | 224 | ||
225 | struct code_page_data | 225 | struct code_page_data |
226 | { | 226 | { |
227 | u32 magic; /* 8945 21f7 */ | 227 | __le32 magic; /* 8945 21f7 */ |
228 | u32 n_used; /* # elements used in c_p_data[] */ | 228 | __le32 n_used; /* # elements used in c_p_data[] */ |
229 | u32 bounds[3]; /* looks a bit like | 229 | __le32 bounds[3]; /* looks a bit like |
230 | (beg1,end1), (beg2,end2) | 230 | (beg1,end1), (beg2,end2) |
231 | one byte each */ | 231 | one byte each */ |
232 | u16 offs[3]; /* offsets from start of sector | 232 | __le16 offs[3]; /* offsets from start of sector |
233 | to start of c_p_data[ix] */ | 233 | to start of c_p_data[ix] */ |
234 | struct { | 234 | struct { |
235 | u16 ix; /* index */ | 235 | __le16 ix; /* index */ |
236 | u16 code_page_number; /* code page number */ | 236 | __le16 code_page_number; /* code page number */ |
237 | u16 unknown; /* the same as in cp directory */ | 237 | __le16 unknown; /* the same as in cp directory */ |
238 | u8 map[128]; /* upcase table for chars 80..ff */ | 238 | u8 map[128]; /* upcase table for chars 80..ff */ |
239 | u16 zero2; | 239 | __le16 zero2; |
240 | } code_page[3]; | 240 | } code_page[3]; |
241 | u8 incognita[78]; | 241 | u8 incognita[78]; |
242 | }; | 242 | }; |
@@ -278,8 +278,8 @@ struct code_page_data | |||
278 | #define DNODE_MAGIC 0x77e40aae | 278 | #define DNODE_MAGIC 0x77e40aae |
279 | 279 | ||
280 | struct dnode { | 280 | struct dnode { |
281 | u32 magic; /* 77e4 0aae */ | 281 | __le32 magic; /* 77e4 0aae */ |
282 | u32 first_free; /* offset from start of dnode to | 282 | __le32 first_free; /* offset from start of dnode to |
283 | first free dir entry */ | 283 | first free dir entry */ |
284 | #ifdef __LITTLE_ENDIAN | 284 | #ifdef __LITTLE_ENDIAN |
285 | u8 root_dnode: 1; /* Is it root dnode? */ | 285 | u8 root_dnode: 1; /* Is it root dnode? */ |
@@ -293,14 +293,14 @@ struct dnode { | |||
293 | u8 root_dnode: 1; /* Is it root dnode? */ | 293 | u8 root_dnode: 1; /* Is it root dnode? */ |
294 | #endif | 294 | #endif |
295 | u8 increment_me2[3]; | 295 | u8 increment_me2[3]; |
296 | secno up; /* (root dnode) directory's fnode | 296 | __le32 up; /* (root dnode) directory's fnode |
297 | (nonroot) parent dnode */ | 297 | (nonroot) parent dnode */ |
298 | dnode_secno self; /* pointer to this dnode */ | 298 | __le32 self; /* pointer to this dnode */ |
299 | u8 dirent[2028]; /* one or more dirents */ | 299 | u8 dirent[2028]; /* one or more dirents */ |
300 | }; | 300 | }; |
301 | 301 | ||
302 | struct hpfs_dirent { | 302 | struct hpfs_dirent { |
303 | u16 length; /* offset to next dirent */ | 303 | __le16 length; /* offset to next dirent */ |
304 | 304 | ||
305 | #ifdef __LITTLE_ENDIAN | 305 | #ifdef __LITTLE_ENDIAN |
306 | u8 first: 1; /* set on phony ^A^A (".") entry */ | 306 | u8 first: 1; /* set on phony ^A^A (".") entry */ |
@@ -346,12 +346,12 @@ struct hpfs_dirent { | |||
346 | u8 read_only: 1; /* dos attrib */ | 346 | u8 read_only: 1; /* dos attrib */ |
347 | #endif | 347 | #endif |
348 | 348 | ||
349 | fnode_secno fnode; /* fnode giving allocation info */ | 349 | __le32 fnode; /* fnode giving allocation info */ |
350 | time32_t write_date; /* mtime */ | 350 | __le32 write_date; /* mtime */ |
351 | u32 file_size; /* file length, bytes */ | 351 | __le32 file_size; /* file length, bytes */ |
352 | time32_t read_date; /* atime */ | 352 | __le32 read_date; /* atime */ |
353 | time32_t creation_date; /* ctime */ | 353 | __le32 creation_date; /* ctime */ |
354 | u32 ea_size; /* total EA length, bytes */ | 354 | __le32 ea_size; /* total EA length, bytes */ |
355 | u8 no_of_acls; /* number of ACL's (low 3 bits) */ | 355 | u8 no_of_acls; /* number of ACL's (low 3 bits) */ |
356 | u8 ix; /* code page index (of filename), see | 356 | u8 ix; /* code page index (of filename), see |
357 | struct code_page_data */ | 357 | struct code_page_data */ |
@@ -375,50 +375,36 @@ struct hpfs_dirent { | |||
375 | 375 | ||
376 | struct bplus_leaf_node | 376 | struct bplus_leaf_node |
377 | { | 377 | { |
378 | u32 file_secno; /* first file sector in extent */ | 378 | __le32 file_secno; /* first file sector in extent */ |
379 | u32 length; /* length, sectors */ | 379 | __le32 length; /* length, sectors */ |
380 | secno disk_secno; /* first corresponding disk sector */ | 380 | __le32 disk_secno; /* first corresponding disk sector */ |
381 | }; | 381 | }; |
382 | 382 | ||
383 | struct bplus_internal_node | 383 | struct bplus_internal_node |
384 | { | 384 | { |
385 | u32 file_secno; /* subtree maps sectors < this */ | 385 | __le32 file_secno; /* subtree maps sectors < this */ |
386 | anode_secno down; /* pointer to subtree */ | 386 | __le32 down; /* pointer to subtree */ |
387 | }; | 387 | }; |
388 | 388 | ||
389 | enum { | ||
390 | BP_hbff = 1, | ||
391 | BP_fnode_parent = 0x20, | ||
392 | BP_binary_search = 0x40, | ||
393 | BP_internal = 0x80 | ||
394 | }; | ||
389 | struct bplus_header | 395 | struct bplus_header |
390 | { | 396 | { |
391 | #ifdef __LITTLE_ENDIAN | 397 | u8 flags; /* bit 0 - high bit of first free entry offset |
392 | u8 hbff: 1; /* high bit of first free entry offset */ | 398 | bit 5 - we're pointed to by an fnode, |
393 | u8 flag1234: 4; | ||
394 | u8 fnode_parent: 1; /* ? we're pointed to by an fnode, | ||
395 | the data btree or some ea or the | ||
396 | main ea bootage pointer ea_secno */ | ||
397 | /* also can get set in fnodes, which | ||
398 | may be a chkdsk glitch or may mean | ||
399 | this bit is irrelevant in fnodes, | ||
400 | or this interpretation is all wet */ | ||
401 | u8 binary_search: 1; /* suggest binary search (unused) */ | ||
402 | u8 internal: 1; /* 1 -> (internal) tree of anodes | ||
403 | 0 -> (leaf) list of extents */ | ||
404 | #else | ||
405 | u8 internal: 1; /* 1 -> (internal) tree of anodes | ||
406 | 0 -> (leaf) list of extents */ | ||
407 | u8 binary_search: 1; /* suggest binary search (unused) */ | ||
408 | u8 fnode_parent: 1; /* ? we're pointed to by an fnode, | ||
409 | the data btree or some ea or the | 399 | the data btree or some ea or the |
410 | main ea bootage pointer ea_secno */ | 400 | main ea bootage pointer ea_secno |
411 | /* also can get set in fnodes, which | 401 | bit 6 - suggest binary search (unused) |
412 | may be a chkdsk glitch or may mean | 402 | bit 7 - 1 -> (internal) tree of anodes |
413 | this bit is irrelevant in fnodes, | 403 | 0 -> (leaf) list of extents */ |
414 | or this interpretation is all wet */ | ||
415 | u8 flag1234: 4; | ||
416 | u8 hbff: 1; /* high bit of first free entry offset */ | ||
417 | #endif | ||
418 | u8 fill[3]; | 404 | u8 fill[3]; |
419 | u8 n_free_nodes; /* free nodes in following array */ | 405 | u8 n_free_nodes; /* free nodes in following array */ |
420 | u8 n_used_nodes; /* used nodes in following array */ | 406 | u8 n_used_nodes; /* used nodes in following array */ |
421 | u16 first_free; /* offset from start of header to | 407 | __le16 first_free; /* offset from start of header to |
422 | first free node in array */ | 408 | first free node in array */ |
423 | union { | 409 | union { |
424 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving | 410 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving |
@@ -428,6 +414,16 @@ struct bplus_header | |||
428 | } u; | 414 | } u; |
429 | }; | 415 | }; |
430 | 416 | ||
417 | static inline bool bp_internal(struct bplus_header *bp) | ||
418 | { | ||
419 | return bp->flags & BP_internal; | ||
420 | } | ||
421 | |||
422 | static inline bool bp_fnode_parent(struct bplus_header *bp) | ||
423 | { | ||
424 | return bp->flags & BP_fnode_parent; | ||
425 | } | ||
426 | |||
431 | /* fnode: root of allocation b+ tree, and EA's */ | 427 | /* fnode: root of allocation b+ tree, and EA's */ |
432 | 428 | ||
433 | /* Every file and every directory has one fnode, pointed to by the directory | 429 | /* Every file and every directory has one fnode, pointed to by the directory |
@@ -436,62 +432,56 @@ struct bplus_header | |||
436 | 432 | ||
437 | #define FNODE_MAGIC 0xf7e40aae | 433 | #define FNODE_MAGIC 0xf7e40aae |
438 | 434 | ||
435 | enum {FNODE_anode = cpu_to_le16(2), FNODE_dir = cpu_to_le16(256)}; | ||
439 | struct fnode | 436 | struct fnode |
440 | { | 437 | { |
441 | u32 magic; /* f7e4 0aae */ | 438 | __le32 magic; /* f7e4 0aae */ |
442 | u32 zero1[2]; /* read history */ | 439 | __le32 zero1[2]; /* read history */ |
443 | u8 len, name[15]; /* true length, truncated name */ | 440 | u8 len, name[15]; /* true length, truncated name */ |
444 | fnode_secno up; /* pointer to file's directory fnode */ | 441 | __le32 up; /* pointer to file's directory fnode */ |
445 | secno acl_size_l; | 442 | __le32 acl_size_l; |
446 | secno acl_secno; | 443 | __le32 acl_secno; |
447 | u16 acl_size_s; | 444 | __le16 acl_size_s; |
448 | u8 acl_anode; | 445 | u8 acl_anode; |
449 | u8 zero2; /* history bit count */ | 446 | u8 zero2; /* history bit count */ |
450 | u32 ea_size_l; /* length of disk-resident ea's */ | 447 | __le32 ea_size_l; /* length of disk-resident ea's */ |
451 | secno ea_secno; /* first sector of disk-resident ea's*/ | 448 | __le32 ea_secno; /* first sector of disk-resident ea's*/ |
452 | u16 ea_size_s; /* length of fnode-resident ea's */ | 449 | __le16 ea_size_s; /* length of fnode-resident ea's */ |
453 | |||
454 | #ifdef __LITTLE_ENDIAN | ||
455 | u8 flag0: 1; | ||
456 | u8 ea_anode: 1; /* 1 -> ea_secno is an anode */ | ||
457 | u8 flag234567: 6; | ||
458 | #else | ||
459 | u8 flag234567: 6; | ||
460 | u8 ea_anode: 1; /* 1 -> ea_secno is an anode */ | ||
461 | u8 flag0: 1; | ||
462 | #endif | ||
463 | 450 | ||
464 | #ifdef __LITTLE_ENDIAN | 451 | __le16 flags; /* bit 1 set -> ea_secno is an anode */ |
465 | u8 dirflag: 1; /* 1 -> directory. first & only extent | 452 | /* bit 8 set -> directory. first & only extent |
466 | points to dnode. */ | ||
467 | u8 flag9012345: 7; | ||
468 | #else | ||
469 | u8 flag9012345: 7; | ||
470 | u8 dirflag: 1; /* 1 -> directory. first & only extent | ||
471 | points to dnode. */ | 453 | points to dnode. */ |
472 | #endif | ||
473 | |||
474 | struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ | 454 | struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ |
475 | union { | 455 | union { |
476 | struct bplus_leaf_node external[8]; | 456 | struct bplus_leaf_node external[8]; |
477 | struct bplus_internal_node internal[12]; | 457 | struct bplus_internal_node internal[12]; |
478 | } u; | 458 | } u; |
479 | 459 | ||
480 | u32 file_size; /* file length, bytes */ | 460 | __le32 file_size; /* file length, bytes */ |
481 | u32 n_needea; /* number of EA's with NEEDEA set */ | 461 | __le32 n_needea; /* number of EA's with NEEDEA set */ |
482 | u8 user_id[16]; /* unused */ | 462 | u8 user_id[16]; /* unused */ |
483 | u16 ea_offs; /* offset from start of fnode | 463 | __le16 ea_offs; /* offset from start of fnode |
484 | to first fnode-resident ea */ | 464 | to first fnode-resident ea */ |
485 | u8 dasd_limit_treshhold; | 465 | u8 dasd_limit_treshhold; |
486 | u8 dasd_limit_delta; | 466 | u8 dasd_limit_delta; |
487 | u32 dasd_limit; | 467 | __le32 dasd_limit; |
488 | u32 dasd_usage; | 468 | __le32 dasd_usage; |
489 | u8 ea[316]; /* zero or more EA's, packed together | 469 | u8 ea[316]; /* zero or more EA's, packed together |
490 | with no alignment padding. | 470 | with no alignment padding. |
491 | (Do not use this name, get here | 471 | (Do not use this name, get here |
492 | via fnode + ea_offs. I think.) */ | 472 | via fnode + ea_offs. I think.) */ |
493 | }; | 473 | }; |
494 | 474 | ||
475 | static inline bool fnode_in_anode(struct fnode *p) | ||
476 | { | ||
477 | return (p->flags & FNODE_anode) != 0; | ||
478 | } | ||
479 | |||
480 | static inline bool fnode_is_dir(struct fnode *p) | ||
481 | { | ||
482 | return (p->flags & FNODE_dir) != 0; | ||
483 | } | ||
484 | |||
495 | 485 | ||
496 | /* anode: 99.44% pure allocation tree */ | 486 | /* anode: 99.44% pure allocation tree */ |
497 | 487 | ||
@@ -499,9 +489,9 @@ struct fnode | |||
499 | 489 | ||
500 | struct anode | 490 | struct anode |
501 | { | 491 | { |
502 | u32 magic; /* 37e4 0aae */ | 492 | __le32 magic; /* 37e4 0aae */ |
503 | anode_secno self; /* pointer to this anode */ | 493 | __le32 self; /* pointer to this anode */ |
504 | secno up; /* parent anode or fnode */ | 494 | __le32 up; /* parent anode or fnode */ |
505 | 495 | ||
506 | struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */ | 496 | struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */ |
507 | union { | 497 | union { |
@@ -509,7 +499,7 @@ struct anode | |||
509 | struct bplus_internal_node internal[60]; | 499 | struct bplus_internal_node internal[60]; |
510 | } u; | 500 | } u; |
511 | 501 | ||
512 | u32 fill[3]; /* unused */ | 502 | __le32 fill[3]; /* unused */ |
513 | }; | 503 | }; |
514 | 504 | ||
515 | 505 | ||
@@ -528,32 +518,23 @@ struct anode | |||
528 | run, or in multiple runs. Flags in the fnode tell whether the EA list | 518 | run, or in multiple runs. Flags in the fnode tell whether the EA list |
529 | is immediate, in a single run, or in multiple runs. */ | 519 | is immediate, in a single run, or in multiple runs. */ |
530 | 520 | ||
521 | enum {EA_indirect = 1, EA_anode = 2, EA_needea = 128 }; | ||
531 | struct extended_attribute | 522 | struct extended_attribute |
532 | { | 523 | { |
533 | #ifdef __LITTLE_ENDIAN | 524 | u8 flags; /* bit 0 set -> value gives sector number |
534 | u8 indirect: 1; /* 1 -> value gives sector number | ||
535 | where real value starts */ | 525 | where real value starts */ |
536 | u8 anode: 1; /* 1 -> sector is an anode | 526 | /* bit 1 set -> sector is an anode |
537 | that points to fragmented value */ | 527 | that points to fragmented value */ |
538 | u8 flag23456: 5; | 528 | /* bit 7 set -> required ea */ |
539 | u8 needea: 1; /* required ea */ | ||
540 | #else | ||
541 | u8 needea: 1; /* required ea */ | ||
542 | u8 flag23456: 5; | ||
543 | u8 anode: 1; /* 1 -> sector is an anode | ||
544 | that points to fragmented value */ | ||
545 | u8 indirect: 1; /* 1 -> value gives sector number | ||
546 | where real value starts */ | ||
547 | #endif | ||
548 | u8 namelen; /* length of name, bytes */ | 529 | u8 namelen; /* length of name, bytes */ |
549 | u8 valuelen_lo; /* length of value, bytes */ | 530 | u8 valuelen_lo; /* length of value, bytes */ |
550 | u8 valuelen_hi; /* length of value, bytes */ | 531 | u8 valuelen_hi; /* length of value, bytes */ |
551 | u8 name[0]; | 532 | u8 name[]; |
552 | /* | 533 | /* |
553 | u8 name[namelen]; ascii attrib name | 534 | u8 name[namelen]; ascii attrib name |
554 | u8 nul; terminating '\0', not counted | 535 | u8 nul; terminating '\0', not counted |
555 | u8 value[valuelen]; value, arbitrary | 536 | u8 value[valuelen]; value, arbitrary |
556 | if this.indirect, valuelen is 8 and the value is | 537 | if this.flags & 1, valuelen is 8 and the value is |
557 | u32 length; real length of value, bytes | 538 | u32 length; real length of value, bytes |
558 | secno secno; sector address where it starts | 539 | secno secno; sector address where it starts |
559 | if this.anode, the above sector number is the root of an anode tree | 540 | if this.anode, the above sector number is the root of an anode tree |
@@ -561,6 +542,16 @@ struct extended_attribute | |||
561 | */ | 542 | */ |
562 | }; | 543 | }; |
563 | 544 | ||
545 | static inline bool ea_indirect(struct extended_attribute *ea) | ||
546 | { | ||
547 | return ea->flags & EA_indirect; | ||
548 | } | ||
549 | |||
550 | static inline bool ea_in_anode(struct extended_attribute *ea) | ||
551 | { | ||
552 | return ea->flags & EA_anode; | ||
553 | } | ||
554 | |||
564 | /* | 555 | /* |
565 | Local Variables: | 556 | Local Variables: |
566 | comment-column: 40 | 557 | comment-column: 40 |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 6d2d5008fa43..c07ef1f1ced6 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -75,7 +75,7 @@ struct hpfs_sb_info { | |||
75 | unsigned char *sb_cp_table; /* code page tables: */ | 75 | unsigned char *sb_cp_table; /* code page tables: */ |
76 | /* 128 bytes uppercasing table & */ | 76 | /* 128 bytes uppercasing table & */ |
77 | /* 128 bytes lowercasing table */ | 77 | /* 128 bytes lowercasing table */ |
78 | unsigned *sb_bmp_dir; /* main bitmap directory */ | 78 | __le32 *sb_bmp_dir; /* main bitmap directory */ |
79 | unsigned sb_c_bitmap; /* current bitmap */ | 79 | unsigned sb_c_bitmap; /* current bitmap */ |
80 | unsigned sb_max_fwd_alloc; /* max forwad allocation */ | 80 | unsigned sb_max_fwd_alloc; /* max forwad allocation */ |
81 | int sb_timeshift; | 81 | int sb_timeshift; |
@@ -93,7 +93,7 @@ struct quad_buffer_head { | |||
93 | static inline dnode_secno de_down_pointer (struct hpfs_dirent *de) | 93 | static inline dnode_secno de_down_pointer (struct hpfs_dirent *de) |
94 | { | 94 | { |
95 | CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n")); | 95 | CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n")); |
96 | return le32_to_cpu(*(dnode_secno *) ((void *) de + le16_to_cpu(de->length) - 4)); | 96 | return le32_to_cpu(*(__le32 *) ((void *) de + le16_to_cpu(de->length) - 4)); |
97 | } | 97 | } |
98 | 98 | ||
99 | /* The first dir entry in a dnode */ | 99 | /* The first dir entry in a dnode */ |
@@ -141,12 +141,12 @@ static inline struct extended_attribute *next_ea(struct extended_attribute *ea) | |||
141 | 141 | ||
142 | static inline secno ea_sec(struct extended_attribute *ea) | 142 | static inline secno ea_sec(struct extended_attribute *ea) |
143 | { | 143 | { |
144 | return le32_to_cpu(get_unaligned((secno *)((char *)ea + 9 + ea->namelen))); | 144 | return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 9 + ea->namelen))); |
145 | } | 145 | } |
146 | 146 | ||
147 | static inline secno ea_len(struct extended_attribute *ea) | 147 | static inline secno ea_len(struct extended_attribute *ea) |
148 | { | 148 | { |
149 | return le32_to_cpu(get_unaligned((secno *)((char *)ea + 5 + ea->namelen))); | 149 | return le32_to_cpu(get_unaligned((__le32 *)((char *)ea + 5 + ea->namelen))); |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline char *ea_data(struct extended_attribute *ea) | 152 | static inline char *ea_data(struct extended_attribute *ea) |
@@ -171,7 +171,7 @@ static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src) | |||
171 | dst->not_8x3 = n; | 171 | dst->not_8x3 = n; |
172 | } | 172 | } |
173 | 173 | ||
174 | static inline unsigned tstbits(u32 *bmp, unsigned b, unsigned n) | 174 | static inline unsigned tstbits(__le32 *bmp, unsigned b, unsigned n) |
175 | { | 175 | { |
176 | int i; | 176 | int i; |
177 | if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n; | 177 | if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n; |
@@ -268,10 +268,10 @@ void hpfs_evict_inode(struct inode *); | |||
268 | 268 | ||
269 | /* map.c */ | 269 | /* map.c */ |
270 | 270 | ||
271 | unsigned *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *); | 271 | __le32 *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *); |
272 | unsigned *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *); | 272 | __le32 *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *); |
273 | unsigned char *hpfs_load_code_page(struct super_block *, secno); | 273 | unsigned char *hpfs_load_code_page(struct super_block *, secno); |
274 | secno *hpfs_load_bitmap_directory(struct super_block *, secno bmp); | 274 | __le32 *hpfs_load_bitmap_directory(struct super_block *, secno bmp); |
275 | struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **); | 275 | struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **); |
276 | struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **); | 276 | struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **); |
277 | struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *); | 277 | struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *); |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index b43066cbdc6a..ed671e0ea784 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -110,7 +110,7 @@ void hpfs_read_inode(struct inode *i) | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | } | 112 | } |
113 | if (fnode->dirflag) { | 113 | if (fnode_is_dir(fnode)) { |
114 | int n_dnodes, n_subdirs; | 114 | int n_dnodes, n_subdirs; |
115 | i->i_mode |= S_IFDIR; | 115 | i->i_mode |= S_IFDIR; |
116 | i->i_op = &hpfs_dir_iops; | 116 | i->i_op = &hpfs_dir_iops; |
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index a790821366a7..4acb19d78359 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c | |||
@@ -8,12 +8,12 @@ | |||
8 | 8 | ||
9 | #include "hpfs_fn.h" | 9 | #include "hpfs_fn.h" |
10 | 10 | ||
11 | unsigned *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh) | 11 | __le32 *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh) |
12 | { | 12 | { |
13 | return hpfs_map_4sectors(s, hpfs_sb(s)->sb_dmap, qbh, 0); | 13 | return hpfs_map_4sectors(s, hpfs_sb(s)->sb_dmap, qbh, 0); |
14 | } | 14 | } |
15 | 15 | ||
16 | unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block, | 16 | __le32 *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block, |
17 | struct quad_buffer_head *qbh, char *id) | 17 | struct quad_buffer_head *qbh, char *id) |
18 | { | 18 | { |
19 | secno sec; | 19 | secno sec; |
@@ -89,18 +89,18 @@ unsigned char *hpfs_load_code_page(struct super_block *s, secno cps) | |||
89 | return cp_table; | 89 | return cp_table; |
90 | } | 90 | } |
91 | 91 | ||
92 | secno *hpfs_load_bitmap_directory(struct super_block *s, secno bmp) | 92 | __le32 *hpfs_load_bitmap_directory(struct super_block *s, secno bmp) |
93 | { | 93 | { |
94 | struct buffer_head *bh; | 94 | struct buffer_head *bh; |
95 | int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21; | 95 | int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21; |
96 | int i; | 96 | int i; |
97 | secno *b; | 97 | __le32 *b; |
98 | if (!(b = kmalloc(n * 512, GFP_KERNEL))) { | 98 | if (!(b = kmalloc(n * 512, GFP_KERNEL))) { |
99 | printk("HPFS: can't allocate memory for bitmap directory\n"); | 99 | printk("HPFS: can't allocate memory for bitmap directory\n"); |
100 | return NULL; | 100 | return NULL; |
101 | } | 101 | } |
102 | for (i=0;i<n;i++) { | 102 | for (i=0;i<n;i++) { |
103 | secno *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1); | 103 | __le32 *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1); |
104 | if (!d) { | 104 | if (!d) { |
105 | kfree(b); | 105 | kfree(b); |
106 | return NULL; | 106 | return NULL; |
@@ -130,16 +130,16 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea | |||
130 | (unsigned long)ino); | 130 | (unsigned long)ino); |
131 | goto bail; | 131 | goto bail; |
132 | } | 132 | } |
133 | if (!fnode->dirflag) { | 133 | if (!fnode_is_dir(fnode)) { |
134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != | 134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != |
135 | (fnode->btree.internal ? 12 : 8)) { | 135 | (bp_internal(&fnode->btree) ? 12 : 8)) { |
136 | hpfs_error(s, | 136 | hpfs_error(s, |
137 | "bad number of nodes in fnode %08lx", | 137 | "bad number of nodes in fnode %08lx", |
138 | (unsigned long)ino); | 138 | (unsigned long)ino); |
139 | goto bail; | 139 | goto bail; |
140 | } | 140 | } |
141 | if (le16_to_cpu(fnode->btree.first_free) != | 141 | if (le16_to_cpu(fnode->btree.first_free) != |
142 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { | 142 | 8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) { |
143 | hpfs_error(s, | 143 | hpfs_error(s, |
144 | "bad first_free pointer in fnode %08lx", | 144 | "bad first_free pointer in fnode %08lx", |
145 | (unsigned long)ino); | 145 | (unsigned long)ino); |
@@ -187,12 +187,12 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff | |||
187 | goto bail; | 187 | goto bail; |
188 | } | 188 | } |
189 | if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != | 189 | if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != |
190 | (anode->btree.internal ? 60 : 40)) { | 190 | (bp_internal(&anode->btree) ? 60 : 40)) { |
191 | hpfs_error(s, "bad number of nodes in anode %08x", ano); | 191 | hpfs_error(s, "bad number of nodes in anode %08x", ano); |
192 | goto bail; | 192 | goto bail; |
193 | } | 193 | } |
194 | if (le16_to_cpu(anode->btree.first_free) != | 194 | if (le16_to_cpu(anode->btree.first_free) != |
195 | 8 + anode->btree.n_used_nodes * (anode->btree.internal ? 8 : 12)) { | 195 | 8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) { |
196 | hpfs_error(s, "bad first_free pointer in anode %08x", ano); | 196 | hpfs_error(s, "bad first_free pointer in anode %08x", ano); |
197 | goto bail; | 197 | goto bail; |
198 | } | 198 | } |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 30dd7b10b507..9083ef8af58c 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -70,7 +70,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
70 | fnode->len = len; | 70 | fnode->len = len; |
71 | memcpy(fnode->name, name, len > 15 ? 15 : len); | 71 | memcpy(fnode->name, name, len > 15 ? 15 : len); |
72 | fnode->up = cpu_to_le32(dir->i_ino); | 72 | fnode->up = cpu_to_le32(dir->i_ino); |
73 | fnode->dirflag = 1; | 73 | fnode->flags |= FNODE_dir; |
74 | fnode->btree.n_free_nodes = 7; | 74 | fnode->btree.n_free_nodes = 7; |
75 | fnode->btree.n_used_nodes = 1; | 75 | fnode->btree.n_used_nodes = 1; |
76 | fnode->btree.first_free = cpu_to_le16(0x14); | 76 | fnode->btree.first_free = cpu_to_le16(0x14); |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 54f6eccb79d9..706a12c083ea 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -572,7 +572,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
572 | mark_buffer_dirty(bh2); | 572 | mark_buffer_dirty(bh2); |
573 | } | 573 | } |
574 | 574 | ||
575 | if (le32_to_cpu(spareblock->hotfixes_used) || le32_to_cpu(spareblock->n_spares_used)) { | 575 | if (spareblock->hotfixes_used || spareblock->n_spares_used) { |
576 | if (errs >= 2) { | 576 | if (errs >= 2) { |
577 | printk("HPFS: Hotfixes not supported here, try chkdsk\n"); | 577 | printk("HPFS: Hotfixes not supported here, try chkdsk\n"); |
578 | mark_dirty(s, 0); | 578 | mark_dirty(s, 0); |
@@ -645,7 +645,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
645 | root->i_mtime.tv_nsec = 0; | 645 | root->i_mtime.tv_nsec = 0; |
646 | root->i_ctime.tv_sec = local_to_gmt(s, le32_to_cpu(de->creation_date)); | 646 | root->i_ctime.tv_sec = local_to_gmt(s, le32_to_cpu(de->creation_date)); |
647 | root->i_ctime.tv_nsec = 0; | 647 | root->i_ctime.tv_nsec = 0; |
648 | hpfs_i(root)->i_ea_size = le16_to_cpu(de->ea_size); | 648 | hpfs_i(root)->i_ea_size = le32_to_cpu(de->ea_size); |
649 | hpfs_i(root)->i_parent_dir = root->i_ino; | 649 | hpfs_i(root)->i_parent_dir = root->i_ino; |
650 | if (root->i_size == -1) | 650 | if (root->i_size == -1) |
651 | root->i_size = 2048; | 651 | root->i_size = 2048; |
diff --git a/fs/inode.c b/fs/inode.c index c474c1d7062b..c99163b1b310 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1487,10 +1487,30 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, | |||
1487 | return 0; | 1487 | return 0; |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | /* | ||
1491 | * This does the actual work of updating an inodes time or version. Must have | ||
1492 | * had called mnt_want_write() before calling this. | ||
1493 | */ | ||
1494 | static int update_time(struct inode *inode, struct timespec *time, int flags) | ||
1495 | { | ||
1496 | if (inode->i_op->update_time) | ||
1497 | return inode->i_op->update_time(inode, time, flags); | ||
1498 | |||
1499 | if (flags & S_ATIME) | ||
1500 | inode->i_atime = *time; | ||
1501 | if (flags & S_VERSION) | ||
1502 | inode_inc_iversion(inode); | ||
1503 | if (flags & S_CTIME) | ||
1504 | inode->i_ctime = *time; | ||
1505 | if (flags & S_MTIME) | ||
1506 | inode->i_mtime = *time; | ||
1507 | mark_inode_dirty_sync(inode); | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1490 | /** | 1511 | /** |
1491 | * touch_atime - update the access time | 1512 | * touch_atime - update the access time |
1492 | * @mnt: mount the inode is accessed on | 1513 | * @path: the &struct path to update |
1493 | * @dentry: dentry accessed | ||
1494 | * | 1514 | * |
1495 | * Update the accessed time on an inode and mark it for writeback. | 1515 | * Update the accessed time on an inode and mark it for writeback. |
1496 | * This function automatically handles read only file systems and media, | 1516 | * This function automatically handles read only file systems and media, |
@@ -1525,12 +1545,83 @@ void touch_atime(struct path *path) | |||
1525 | if (mnt_want_write(mnt)) | 1545 | if (mnt_want_write(mnt)) |
1526 | return; | 1546 | return; |
1527 | 1547 | ||
1528 | inode->i_atime = now; | 1548 | /* |
1529 | mark_inode_dirty_sync(inode); | 1549 | * File systems can error out when updating inodes if they need to |
1550 | * allocate new space to modify an inode (such is the case for | ||
1551 | * Btrfs), but since we touch atime while walking down the path we | ||
1552 | * really don't care if we failed to update the atime of the file, | ||
1553 | * so just ignore the return value. | ||
1554 | */ | ||
1555 | update_time(inode, &now, S_ATIME); | ||
1530 | mnt_drop_write(mnt); | 1556 | mnt_drop_write(mnt); |
1531 | } | 1557 | } |
1532 | EXPORT_SYMBOL(touch_atime); | 1558 | EXPORT_SYMBOL(touch_atime); |
1533 | 1559 | ||
1560 | /* | ||
1561 | * The logic we want is | ||
1562 | * | ||
1563 | * if suid or (sgid and xgrp) | ||
1564 | * remove privs | ||
1565 | */ | ||
1566 | int should_remove_suid(struct dentry *dentry) | ||
1567 | { | ||
1568 | umode_t mode = dentry->d_inode->i_mode; | ||
1569 | int kill = 0; | ||
1570 | |||
1571 | /* suid always must be killed */ | ||
1572 | if (unlikely(mode & S_ISUID)) | ||
1573 | kill = ATTR_KILL_SUID; | ||
1574 | |||
1575 | /* | ||
1576 | * sgid without any exec bits is just a mandatory locking mark; leave | ||
1577 | * it alone. If some exec bits are set, it's a real sgid; kill it. | ||
1578 | */ | ||
1579 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) | ||
1580 | kill |= ATTR_KILL_SGID; | ||
1581 | |||
1582 | if (unlikely(kill && !capable(CAP_FSETID) && S_ISREG(mode))) | ||
1583 | return kill; | ||
1584 | |||
1585 | return 0; | ||
1586 | } | ||
1587 | EXPORT_SYMBOL(should_remove_suid); | ||
1588 | |||
1589 | static int __remove_suid(struct dentry *dentry, int kill) | ||
1590 | { | ||
1591 | struct iattr newattrs; | ||
1592 | |||
1593 | newattrs.ia_valid = ATTR_FORCE | kill; | ||
1594 | return notify_change(dentry, &newattrs); | ||
1595 | } | ||
1596 | |||
1597 | int file_remove_suid(struct file *file) | ||
1598 | { | ||
1599 | struct dentry *dentry = file->f_path.dentry; | ||
1600 | struct inode *inode = dentry->d_inode; | ||
1601 | int killsuid; | ||
1602 | int killpriv; | ||
1603 | int error = 0; | ||
1604 | |||
1605 | /* Fast path for nothing security related */ | ||
1606 | if (IS_NOSEC(inode)) | ||
1607 | return 0; | ||
1608 | |||
1609 | killsuid = should_remove_suid(dentry); | ||
1610 | killpriv = security_inode_need_killpriv(dentry); | ||
1611 | |||
1612 | if (killpriv < 0) | ||
1613 | return killpriv; | ||
1614 | if (killpriv) | ||
1615 | error = security_inode_killpriv(dentry); | ||
1616 | if (!error && killsuid) | ||
1617 | error = __remove_suid(dentry, killsuid); | ||
1618 | if (!error && (inode->i_sb->s_flags & MS_NOSEC)) | ||
1619 | inode->i_flags |= S_NOSEC; | ||
1620 | |||
1621 | return error; | ||
1622 | } | ||
1623 | EXPORT_SYMBOL(file_remove_suid); | ||
1624 | |||
1534 | /** | 1625 | /** |
1535 | * file_update_time - update mtime and ctime time | 1626 | * file_update_time - update mtime and ctime time |
1536 | * @file: file accessed | 1627 | * @file: file accessed |
@@ -1540,18 +1631,20 @@ EXPORT_SYMBOL(touch_atime); | |||
1540 | * usage in the file write path of filesystems, and filesystems may | 1631 | * usage in the file write path of filesystems, and filesystems may |
1541 | * choose to explicitly ignore update via this function with the | 1632 | * choose to explicitly ignore update via this function with the |
1542 | * S_NOCMTIME inode flag, e.g. for network filesystem where these | 1633 | * S_NOCMTIME inode flag, e.g. for network filesystem where these |
1543 | * timestamps are handled by the server. | 1634 | * timestamps are handled by the server. This can return an error for |
1635 | * file systems who need to allocate space in order to update an inode. | ||
1544 | */ | 1636 | */ |
1545 | 1637 | ||
1546 | void file_update_time(struct file *file) | 1638 | int file_update_time(struct file *file) |
1547 | { | 1639 | { |
1548 | struct inode *inode = file->f_path.dentry->d_inode; | 1640 | struct inode *inode = file->f_path.dentry->d_inode; |
1549 | struct timespec now; | 1641 | struct timespec now; |
1550 | enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; | 1642 | int sync_it = 0; |
1643 | int ret; | ||
1551 | 1644 | ||
1552 | /* First try to exhaust all avenues to not sync */ | 1645 | /* First try to exhaust all avenues to not sync */ |
1553 | if (IS_NOCMTIME(inode)) | 1646 | if (IS_NOCMTIME(inode)) |
1554 | return; | 1647 | return 0; |
1555 | 1648 | ||
1556 | now = current_fs_time(inode->i_sb); | 1649 | now = current_fs_time(inode->i_sb); |
1557 | if (!timespec_equal(&inode->i_mtime, &now)) | 1650 | if (!timespec_equal(&inode->i_mtime, &now)) |
@@ -1564,21 +1657,16 @@ void file_update_time(struct file *file) | |||
1564 | sync_it |= S_VERSION; | 1657 | sync_it |= S_VERSION; |
1565 | 1658 | ||
1566 | if (!sync_it) | 1659 | if (!sync_it) |
1567 | return; | 1660 | return 0; |
1568 | 1661 | ||
1569 | /* Finally allowed to write? Takes lock. */ | 1662 | /* Finally allowed to write? Takes lock. */ |
1570 | if (mnt_want_write_file(file)) | 1663 | if (mnt_want_write_file(file)) |
1571 | return; | 1664 | return 0; |
1572 | 1665 | ||
1573 | /* Only change inode inside the lock region */ | 1666 | ret = update_time(inode, &now, sync_it); |
1574 | if (sync_it & S_VERSION) | ||
1575 | inode_inc_iversion(inode); | ||
1576 | if (sync_it & S_CTIME) | ||
1577 | inode->i_ctime = now; | ||
1578 | if (sync_it & S_MTIME) | ||
1579 | inode->i_mtime = now; | ||
1580 | mark_inode_dirty_sync(inode); | ||
1581 | mnt_drop_write_file(file); | 1667 | mnt_drop_write_file(file); |
1668 | |||
1669 | return ret; | ||
1582 | } | 1670 | } |
1583 | EXPORT_SYMBOL(file_update_time); | 1671 | EXPORT_SYMBOL(file_update_time); |
1584 | 1672 | ||
diff --git a/fs/internal.h b/fs/internal.h index 9962c59ba280..18bc216ea09d 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -56,7 +56,7 @@ extern int sb_prepare_remount_readonly(struct super_block *); | |||
56 | 56 | ||
57 | extern void __init mnt_init(void); | 57 | extern void __init mnt_init(void); |
58 | 58 | ||
59 | DECLARE_BRLOCK(vfsmount_lock); | 59 | extern struct lglock vfsmount_lock; |
60 | 60 | ||
61 | 61 | ||
62 | /* | 62 | /* |
@@ -100,6 +100,7 @@ extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, | |||
100 | 100 | ||
101 | extern long do_handle_open(int mountdirfd, | 101 | extern long do_handle_open(int mountdirfd, |
102 | struct file_handle __user *ufh, int open_flag); | 102 | struct file_handle __user *ufh, int open_flag); |
103 | extern int open_check_o_direct(struct file *f); | ||
103 | 104 | ||
104 | /* | 105 | /* |
105 | * inode.c | 106 | * inode.c |
diff --git a/fs/isofs/export.c b/fs/isofs/export.c index dd4687ff30d0..aa4356d09eee 100644 --- a/fs/isofs/export.c +++ b/fs/isofs/export.c | |||
@@ -107,12 +107,11 @@ static struct dentry *isofs_export_get_parent(struct dentry *child) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | static int | 109 | static int |
110 | isofs_export_encode_fh(struct dentry *dentry, | 110 | isofs_export_encode_fh(struct inode *inode, |
111 | __u32 *fh32, | 111 | __u32 *fh32, |
112 | int *max_len, | 112 | int *max_len, |
113 | int connectable) | 113 | struct inode *parent) |
114 | { | 114 | { |
115 | struct inode * inode = dentry->d_inode; | ||
116 | struct iso_inode_info * ei = ISOFS_I(inode); | 115 | struct iso_inode_info * ei = ISOFS_I(inode); |
117 | int len = *max_len; | 116 | int len = *max_len; |
118 | int type = 1; | 117 | int type = 1; |
@@ -124,7 +123,7 @@ isofs_export_encode_fh(struct dentry *dentry, | |||
124 | * offset of the inode and the upper 16 bits of fh32[1] to | 123 | * offset of the inode and the upper 16 bits of fh32[1] to |
125 | * hold the offset of the parent. | 124 | * hold the offset of the parent. |
126 | */ | 125 | */ |
127 | if (connectable && (len < 5)) { | 126 | if (parent && (len < 5)) { |
128 | *max_len = 5; | 127 | *max_len = 5; |
129 | return 255; | 128 | return 255; |
130 | } else if (len < 3) { | 129 | } else if (len < 3) { |
@@ -136,16 +135,12 @@ isofs_export_encode_fh(struct dentry *dentry, | |||
136 | fh32[0] = ei->i_iget5_block; | 135 | fh32[0] = ei->i_iget5_block; |
137 | fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */ | 136 | fh16[2] = (__u16)ei->i_iget5_offset; /* fh16 [sic] */ |
138 | fh32[2] = inode->i_generation; | 137 | fh32[2] = inode->i_generation; |
139 | if (connectable && !S_ISDIR(inode->i_mode)) { | 138 | if (parent) { |
140 | struct inode *parent; | ||
141 | struct iso_inode_info *eparent; | 139 | struct iso_inode_info *eparent; |
142 | spin_lock(&dentry->d_lock); | ||
143 | parent = dentry->d_parent->d_inode; | ||
144 | eparent = ISOFS_I(parent); | 140 | eparent = ISOFS_I(parent); |
145 | fh32[3] = eparent->i_iget5_block; | 141 | fh32[3] = eparent->i_iget5_block; |
146 | fh16[3] = (__u16)eparent->i_iget5_offset; /* fh16 [sic] */ | 142 | fh16[3] = (__u16)eparent->i_iget5_offset; /* fh16 [sic] */ |
147 | fh32[4] = parent->i_generation; | 143 | fh32[4] = parent->i_generation; |
148 | spin_unlock(&dentry->d_lock); | ||
149 | len = 5; | 144 | len = 5; |
150 | type = 2; | 145 | type = 2; |
151 | } | 146 | } |
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 55a0c1dceadf..44dca1f041c5 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -126,6 +126,10 @@ struct jffs2_sb_info { | |||
126 | struct jffs2_inodirty *wbuf_inodes; | 126 | struct jffs2_inodirty *wbuf_inodes; |
127 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ | 127 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ |
128 | 128 | ||
129 | struct delayed_work wbuf_dwork; /* write-buffer write-out work */ | ||
130 | int wbuf_queued; /* non-zero delayed work is queued */ | ||
131 | spinlock_t wbuf_dwork_lock; /* protects wbuf_dwork and and wbuf_queued */ | ||
132 | |||
129 | unsigned char *oobbuf; | 133 | unsigned char *oobbuf; |
130 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ | 134 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ |
131 | #endif | 135 | #endif |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 1cd3aec9d9ae..bcd983d7e7f9 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -95,6 +95,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) | |||
95 | #define jffs2_ubivol(c) (0) | 95 | #define jffs2_ubivol(c) (0) |
96 | #define jffs2_ubivol_setup(c) (0) | 96 | #define jffs2_ubivol_setup(c) (0) |
97 | #define jffs2_ubivol_cleanup(c) do {} while (0) | 97 | #define jffs2_ubivol_cleanup(c) do {} while (0) |
98 | #define jffs2_dirty_trigger(c) do {} while (0) | ||
98 | 99 | ||
99 | #else /* NAND and/or ECC'd NOR support present */ | 100 | #else /* NAND and/or ECC'd NOR support present */ |
100 | 101 | ||
@@ -135,14 +136,10 @@ void jffs2_ubivol_cleanup(struct jffs2_sb_info *c); | |||
135 | #define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && ! (c->mtd->flags & MTD_BIT_WRITEABLE)) | 136 | #define jffs2_nor_wbuf_flash(c) (c->mtd->type == MTD_NORFLASH && ! (c->mtd->flags & MTD_BIT_WRITEABLE)) |
136 | int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c); | 137 | int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c); |
137 | void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c); | 138 | void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c); |
139 | void jffs2_dirty_trigger(struct jffs2_sb_info *c); | ||
138 | 140 | ||
139 | #endif /* WRITEBUFFER */ | 141 | #endif /* WRITEBUFFER */ |
140 | 142 | ||
141 | static inline void jffs2_dirty_trigger(struct jffs2_sb_info *c) | ||
142 | { | ||
143 | OFNI_BS_2SFFJ(c)->s_dirt = 1; | ||
144 | } | ||
145 | |||
146 | /* background.c */ | 143 | /* background.c */ |
147 | int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); | 144 | int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); |
148 | void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c); | 145 | void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c); |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index f9916f312bd8..bc586f204228 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -63,21 +63,6 @@ static void jffs2_i_init_once(void *foo) | |||
63 | inode_init_once(&f->vfs_inode); | 63 | inode_init_once(&f->vfs_inode); |
64 | } | 64 | } |
65 | 65 | ||
66 | static void jffs2_write_super(struct super_block *sb) | ||
67 | { | ||
68 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); | ||
69 | |||
70 | lock_super(sb); | ||
71 | sb->s_dirt = 0; | ||
72 | |||
73 | if (!(sb->s_flags & MS_RDONLY)) { | ||
74 | jffs2_dbg(1, "%s()\n", __func__); | ||
75 | jffs2_flush_wbuf_gc(c, 0); | ||
76 | } | ||
77 | |||
78 | unlock_super(sb); | ||
79 | } | ||
80 | |||
81 | static const char *jffs2_compr_name(unsigned int compr) | 66 | static const char *jffs2_compr_name(unsigned int compr) |
82 | { | 67 | { |
83 | switch (compr) { | 68 | switch (compr) { |
@@ -113,8 +98,6 @@ static int jffs2_sync_fs(struct super_block *sb, int wait) | |||
113 | { | 98 | { |
114 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); | 99 | struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); |
115 | 100 | ||
116 | jffs2_write_super(sb); | ||
117 | |||
118 | mutex_lock(&c->alloc_sem); | 101 | mutex_lock(&c->alloc_sem); |
119 | jffs2_flush_wbuf_pad(c); | 102 | jffs2_flush_wbuf_pad(c); |
120 | mutex_unlock(&c->alloc_sem); | 103 | mutex_unlock(&c->alloc_sem); |
@@ -251,7 +234,6 @@ static const struct super_operations jffs2_super_operations = | |||
251 | .alloc_inode = jffs2_alloc_inode, | 234 | .alloc_inode = jffs2_alloc_inode, |
252 | .destroy_inode =jffs2_destroy_inode, | 235 | .destroy_inode =jffs2_destroy_inode, |
253 | .put_super = jffs2_put_super, | 236 | .put_super = jffs2_put_super, |
254 | .write_super = jffs2_write_super, | ||
255 | .statfs = jffs2_statfs, | 237 | .statfs = jffs2_statfs, |
256 | .remount_fs = jffs2_remount_fs, | 238 | .remount_fs = jffs2_remount_fs, |
257 | .evict_inode = jffs2_evict_inode, | 239 | .evict_inode = jffs2_evict_inode, |
@@ -319,9 +301,6 @@ static void jffs2_put_super (struct super_block *sb) | |||
319 | 301 | ||
320 | jffs2_dbg(2, "%s()\n", __func__); | 302 | jffs2_dbg(2, "%s()\n", __func__); |
321 | 303 | ||
322 | if (sb->s_dirt) | ||
323 | jffs2_write_super(sb); | ||
324 | |||
325 | mutex_lock(&c->alloc_sem); | 304 | mutex_lock(&c->alloc_sem); |
326 | jffs2_flush_wbuf_pad(c); | 305 | jffs2_flush_wbuf_pad(c); |
327 | mutex_unlock(&c->alloc_sem); | 306 | mutex_unlock(&c->alloc_sem); |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 74d9be19df3f..6f4529d3697f 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/writeback.h> | ||
23 | 24 | ||
24 | #include "nodelist.h" | 25 | #include "nodelist.h" |
25 | 26 | ||
@@ -85,7 +86,7 @@ static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino) | |||
85 | { | 86 | { |
86 | struct jffs2_inodirty *new; | 87 | struct jffs2_inodirty *new; |
87 | 88 | ||
88 | /* Mark the superblock dirty so that kupdated will flush... */ | 89 | /* Schedule delayed write-buffer write-out */ |
89 | jffs2_dirty_trigger(c); | 90 | jffs2_dirty_trigger(c); |
90 | 91 | ||
91 | if (jffs2_wbuf_pending_for_ino(c, ino)) | 92 | if (jffs2_wbuf_pending_for_ino(c, ino)) |
@@ -1148,6 +1149,47 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * | |||
1148 | return 1; | 1149 | return 1; |
1149 | } | 1150 | } |
1150 | 1151 | ||
1152 | static struct jffs2_sb_info *work_to_sb(struct work_struct *work) | ||
1153 | { | ||
1154 | struct delayed_work *dwork; | ||
1155 | |||
1156 | dwork = container_of(work, struct delayed_work, work); | ||
1157 | return container_of(dwork, struct jffs2_sb_info, wbuf_dwork); | ||
1158 | } | ||
1159 | |||
1160 | static void delayed_wbuf_sync(struct work_struct *work) | ||
1161 | { | ||
1162 | struct jffs2_sb_info *c = work_to_sb(work); | ||
1163 | struct super_block *sb = OFNI_BS_2SFFJ(c); | ||
1164 | |||
1165 | spin_lock(&c->wbuf_dwork_lock); | ||
1166 | c->wbuf_queued = 0; | ||
1167 | spin_unlock(&c->wbuf_dwork_lock); | ||
1168 | |||
1169 | if (!(sb->s_flags & MS_RDONLY)) { | ||
1170 | jffs2_dbg(1, "%s()\n", __func__); | ||
1171 | jffs2_flush_wbuf_gc(c, 0); | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | void jffs2_dirty_trigger(struct jffs2_sb_info *c) | ||
1176 | { | ||
1177 | struct super_block *sb = OFNI_BS_2SFFJ(c); | ||
1178 | unsigned long delay; | ||
1179 | |||
1180 | if (sb->s_flags & MS_RDONLY) | ||
1181 | return; | ||
1182 | |||
1183 | spin_lock(&c->wbuf_dwork_lock); | ||
1184 | if (!c->wbuf_queued) { | ||
1185 | jffs2_dbg(1, "%s()\n", __func__); | ||
1186 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
1187 | queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay); | ||
1188 | c->wbuf_queued = 1; | ||
1189 | } | ||
1190 | spin_unlock(&c->wbuf_dwork_lock); | ||
1191 | } | ||
1192 | |||
1151 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | 1193 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) |
1152 | { | 1194 | { |
1153 | struct nand_ecclayout *oinfo = c->mtd->ecclayout; | 1195 | struct nand_ecclayout *oinfo = c->mtd->ecclayout; |
@@ -1169,6 +1211,8 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | |||
1169 | 1211 | ||
1170 | /* Initialise write buffer */ | 1212 | /* Initialise write buffer */ |
1171 | init_rwsem(&c->wbuf_sem); | 1213 | init_rwsem(&c->wbuf_sem); |
1214 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1215 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | ||
1172 | c->wbuf_pagesize = c->mtd->writesize; | 1216 | c->wbuf_pagesize = c->mtd->writesize; |
1173 | c->wbuf_ofs = 0xFFFFFFFF; | 1217 | c->wbuf_ofs = 0xFFFFFFFF; |
1174 | 1218 | ||
@@ -1207,8 +1251,8 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { | |||
1207 | 1251 | ||
1208 | /* Initialize write buffer */ | 1252 | /* Initialize write buffer */ |
1209 | init_rwsem(&c->wbuf_sem); | 1253 | init_rwsem(&c->wbuf_sem); |
1210 | 1254 | spin_lock_init(&c->wbuf_dwork_lock); | |
1211 | 1255 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | |
1212 | c->wbuf_pagesize = c->mtd->erasesize; | 1256 | c->wbuf_pagesize = c->mtd->erasesize; |
1213 | 1257 | ||
1214 | /* Find a suitable c->sector_size | 1258 | /* Find a suitable c->sector_size |
@@ -1267,6 +1311,9 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { | |||
1267 | 1311 | ||
1268 | /* Initialize write buffer */ | 1312 | /* Initialize write buffer */ |
1269 | init_rwsem(&c->wbuf_sem); | 1313 | init_rwsem(&c->wbuf_sem); |
1314 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1315 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | ||
1316 | |||
1270 | c->wbuf_pagesize = c->mtd->writesize; | 1317 | c->wbuf_pagesize = c->mtd->writesize; |
1271 | c->wbuf_ofs = 0xFFFFFFFF; | 1318 | c->wbuf_ofs = 0xFFFFFFFF; |
1272 | 1319 | ||
@@ -1299,6 +1346,8 @@ int jffs2_ubivol_setup(struct jffs2_sb_info *c) { | |||
1299 | return 0; | 1346 | return 0; |
1300 | 1347 | ||
1301 | init_rwsem(&c->wbuf_sem); | 1348 | init_rwsem(&c->wbuf_sem); |
1349 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1350 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | ||
1302 | 1351 | ||
1303 | c->wbuf_pagesize = c->mtd->writesize; | 1352 | c->wbuf_pagesize = c->mtd->writesize; |
1304 | c->wbuf_ofs = 0xFFFFFFFF; | 1353 | c->wbuf_ofs = 0xFFFFFFFF; |
diff --git a/fs/locks.c b/fs/locks.c index 4f441e46cef4..814c51d0de47 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1636,12 +1636,13 @@ EXPORT_SYMBOL(flock_lock_file_wait); | |||
1636 | SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) | 1636 | SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) |
1637 | { | 1637 | { |
1638 | struct file *filp; | 1638 | struct file *filp; |
1639 | int fput_needed; | ||
1639 | struct file_lock *lock; | 1640 | struct file_lock *lock; |
1640 | int can_sleep, unlock; | 1641 | int can_sleep, unlock; |
1641 | int error; | 1642 | int error; |
1642 | 1643 | ||
1643 | error = -EBADF; | 1644 | error = -EBADF; |
1644 | filp = fget(fd); | 1645 | filp = fget_light(fd, &fput_needed); |
1645 | if (!filp) | 1646 | if (!filp) |
1646 | goto out; | 1647 | goto out; |
1647 | 1648 | ||
@@ -1674,7 +1675,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) | |||
1674 | locks_free_lock(lock); | 1675 | locks_free_lock(lock); |
1675 | 1676 | ||
1676 | out_putf: | 1677 | out_putf: |
1677 | fput(filp); | 1678 | fput_light(filp, fput_needed); |
1678 | out: | 1679 | out: |
1679 | return error; | 1680 | return error; |
1680 | } | 1681 | } |
diff --git a/fs/namei.c b/fs/namei.c index c651f02c9fec..7d694194024a 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -449,7 +449,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) | |||
449 | mntget(nd->path.mnt); | 449 | mntget(nd->path.mnt); |
450 | 450 | ||
451 | rcu_read_unlock(); | 451 | rcu_read_unlock(); |
452 | br_read_unlock(vfsmount_lock); | 452 | br_read_unlock(&vfsmount_lock); |
453 | nd->flags &= ~LOOKUP_RCU; | 453 | nd->flags &= ~LOOKUP_RCU; |
454 | return 0; | 454 | return 0; |
455 | 455 | ||
@@ -507,14 +507,14 @@ static int complete_walk(struct nameidata *nd) | |||
507 | if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { | 507 | if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) { |
508 | spin_unlock(&dentry->d_lock); | 508 | spin_unlock(&dentry->d_lock); |
509 | rcu_read_unlock(); | 509 | rcu_read_unlock(); |
510 | br_read_unlock(vfsmount_lock); | 510 | br_read_unlock(&vfsmount_lock); |
511 | return -ECHILD; | 511 | return -ECHILD; |
512 | } | 512 | } |
513 | BUG_ON(nd->inode != dentry->d_inode); | 513 | BUG_ON(nd->inode != dentry->d_inode); |
514 | spin_unlock(&dentry->d_lock); | 514 | spin_unlock(&dentry->d_lock); |
515 | mntget(nd->path.mnt); | 515 | mntget(nd->path.mnt); |
516 | rcu_read_unlock(); | 516 | rcu_read_unlock(); |
517 | br_read_unlock(vfsmount_lock); | 517 | br_read_unlock(&vfsmount_lock); |
518 | } | 518 | } |
519 | 519 | ||
520 | if (likely(!(nd->flags & LOOKUP_JUMPED))) | 520 | if (likely(!(nd->flags & LOOKUP_JUMPED))) |
@@ -681,15 +681,15 @@ int follow_up(struct path *path) | |||
681 | struct mount *parent; | 681 | struct mount *parent; |
682 | struct dentry *mountpoint; | 682 | struct dentry *mountpoint; |
683 | 683 | ||
684 | br_read_lock(vfsmount_lock); | 684 | br_read_lock(&vfsmount_lock); |
685 | parent = mnt->mnt_parent; | 685 | parent = mnt->mnt_parent; |
686 | if (&parent->mnt == path->mnt) { | 686 | if (&parent->mnt == path->mnt) { |
687 | br_read_unlock(vfsmount_lock); | 687 | br_read_unlock(&vfsmount_lock); |
688 | return 0; | 688 | return 0; |
689 | } | 689 | } |
690 | mntget(&parent->mnt); | 690 | mntget(&parent->mnt); |
691 | mountpoint = dget(mnt->mnt_mountpoint); | 691 | mountpoint = dget(mnt->mnt_mountpoint); |
692 | br_read_unlock(vfsmount_lock); | 692 | br_read_unlock(&vfsmount_lock); |
693 | dput(path->dentry); | 693 | dput(path->dentry); |
694 | path->dentry = mountpoint; | 694 | path->dentry = mountpoint; |
695 | mntput(path->mnt); | 695 | mntput(path->mnt); |
@@ -947,7 +947,7 @@ failed: | |||
947 | if (!(nd->flags & LOOKUP_ROOT)) | 947 | if (!(nd->flags & LOOKUP_ROOT)) |
948 | nd->root.mnt = NULL; | 948 | nd->root.mnt = NULL; |
949 | rcu_read_unlock(); | 949 | rcu_read_unlock(); |
950 | br_read_unlock(vfsmount_lock); | 950 | br_read_unlock(&vfsmount_lock); |
951 | return -ECHILD; | 951 | return -ECHILD; |
952 | } | 952 | } |
953 | 953 | ||
@@ -1125,8 +1125,8 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1125 | * small and for now I'd prefer to have fast path as straight as possible. | 1125 | * small and for now I'd prefer to have fast path as straight as possible. |
1126 | * It _is_ time-critical. | 1126 | * It _is_ time-critical. |
1127 | */ | 1127 | */ |
1128 | static int do_lookup(struct nameidata *nd, struct qstr *name, | 1128 | static int lookup_fast(struct nameidata *nd, struct qstr *name, |
1129 | struct path *path, struct inode **inode) | 1129 | struct path *path, struct inode **inode) |
1130 | { | 1130 | { |
1131 | struct vfsmount *mnt = nd->path.mnt; | 1131 | struct vfsmount *mnt = nd->path.mnt; |
1132 | struct dentry *dentry, *parent = nd->path.dentry; | 1132 | struct dentry *dentry, *parent = nd->path.dentry; |
@@ -1208,7 +1208,7 @@ unlazy: | |||
1208 | goto need_lookup; | 1208 | goto need_lookup; |
1209 | } | 1209 | } |
1210 | } | 1210 | } |
1211 | done: | 1211 | |
1212 | path->mnt = mnt; | 1212 | path->mnt = mnt; |
1213 | path->dentry = dentry; | 1213 | path->dentry = dentry; |
1214 | err = follow_managed(path, nd->flags); | 1214 | err = follow_managed(path, nd->flags); |
@@ -1222,6 +1222,17 @@ done: | |||
1222 | return 0; | 1222 | return 0; |
1223 | 1223 | ||
1224 | need_lookup: | 1224 | need_lookup: |
1225 | return 1; | ||
1226 | } | ||
1227 | |||
1228 | /* Fast lookup failed, do it the slow way */ | ||
1229 | static int lookup_slow(struct nameidata *nd, struct qstr *name, | ||
1230 | struct path *path) | ||
1231 | { | ||
1232 | struct dentry *dentry, *parent; | ||
1233 | int err; | ||
1234 | |||
1235 | parent = nd->path.dentry; | ||
1225 | BUG_ON(nd->inode != parent->d_inode); | 1236 | BUG_ON(nd->inode != parent->d_inode); |
1226 | 1237 | ||
1227 | mutex_lock(&parent->d_inode->i_mutex); | 1238 | mutex_lock(&parent->d_inode->i_mutex); |
@@ -1229,7 +1240,16 @@ need_lookup: | |||
1229 | mutex_unlock(&parent->d_inode->i_mutex); | 1240 | mutex_unlock(&parent->d_inode->i_mutex); |
1230 | if (IS_ERR(dentry)) | 1241 | if (IS_ERR(dentry)) |
1231 | return PTR_ERR(dentry); | 1242 | return PTR_ERR(dentry); |
1232 | goto done; | 1243 | path->mnt = nd->path.mnt; |
1244 | path->dentry = dentry; | ||
1245 | err = follow_managed(path, nd->flags); | ||
1246 | if (unlikely(err < 0)) { | ||
1247 | path_put_conditional(path, nd); | ||
1248 | return err; | ||
1249 | } | ||
1250 | if (err) | ||
1251 | nd->flags |= LOOKUP_JUMPED; | ||
1252 | return 0; | ||
1233 | } | 1253 | } |
1234 | 1254 | ||
1235 | static inline int may_lookup(struct nameidata *nd) | 1255 | static inline int may_lookup(struct nameidata *nd) |
@@ -1265,7 +1285,7 @@ static void terminate_walk(struct nameidata *nd) | |||
1265 | if (!(nd->flags & LOOKUP_ROOT)) | 1285 | if (!(nd->flags & LOOKUP_ROOT)) |
1266 | nd->root.mnt = NULL; | 1286 | nd->root.mnt = NULL; |
1267 | rcu_read_unlock(); | 1287 | rcu_read_unlock(); |
1268 | br_read_unlock(vfsmount_lock); | 1288 | br_read_unlock(&vfsmount_lock); |
1269 | } | 1289 | } |
1270 | } | 1290 | } |
1271 | 1291 | ||
@@ -1301,21 +1321,26 @@ static inline int walk_component(struct nameidata *nd, struct path *path, | |||
1301 | */ | 1321 | */ |
1302 | if (unlikely(type != LAST_NORM)) | 1322 | if (unlikely(type != LAST_NORM)) |
1303 | return handle_dots(nd, type); | 1323 | return handle_dots(nd, type); |
1304 | err = do_lookup(nd, name, path, &inode); | 1324 | err = lookup_fast(nd, name, path, &inode); |
1305 | if (unlikely(err)) { | 1325 | if (unlikely(err)) { |
1306 | terminate_walk(nd); | 1326 | if (err < 0) |
1307 | return err; | 1327 | goto out_err; |
1308 | } | 1328 | |
1309 | if (!inode) { | 1329 | err = lookup_slow(nd, name, path); |
1310 | path_to_nameidata(path, nd); | 1330 | if (err < 0) |
1311 | terminate_walk(nd); | 1331 | goto out_err; |
1312 | return -ENOENT; | 1332 | |
1333 | inode = path->dentry->d_inode; | ||
1313 | } | 1334 | } |
1335 | err = -ENOENT; | ||
1336 | if (!inode) | ||
1337 | goto out_path_put; | ||
1338 | |||
1314 | if (should_follow_link(inode, follow)) { | 1339 | if (should_follow_link(inode, follow)) { |
1315 | if (nd->flags & LOOKUP_RCU) { | 1340 | if (nd->flags & LOOKUP_RCU) { |
1316 | if (unlikely(unlazy_walk(nd, path->dentry))) { | 1341 | if (unlikely(unlazy_walk(nd, path->dentry))) { |
1317 | terminate_walk(nd); | 1342 | err = -ECHILD; |
1318 | return -ECHILD; | 1343 | goto out_err; |
1319 | } | 1344 | } |
1320 | } | 1345 | } |
1321 | BUG_ON(inode != path->dentry->d_inode); | 1346 | BUG_ON(inode != path->dentry->d_inode); |
@@ -1324,6 +1349,12 @@ static inline int walk_component(struct nameidata *nd, struct path *path, | |||
1324 | path_to_nameidata(path, nd); | 1349 | path_to_nameidata(path, nd); |
1325 | nd->inode = inode; | 1350 | nd->inode = inode; |
1326 | return 0; | 1351 | return 0; |
1352 | |||
1353 | out_path_put: | ||
1354 | path_to_nameidata(path, nd); | ||
1355 | out_err: | ||
1356 | terminate_walk(nd); | ||
1357 | return err; | ||
1327 | } | 1358 | } |
1328 | 1359 | ||
1329 | /* | 1360 | /* |
@@ -1620,7 +1651,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1620 | nd->path = nd->root; | 1651 | nd->path = nd->root; |
1621 | nd->inode = inode; | 1652 | nd->inode = inode; |
1622 | if (flags & LOOKUP_RCU) { | 1653 | if (flags & LOOKUP_RCU) { |
1623 | br_read_lock(vfsmount_lock); | 1654 | br_read_lock(&vfsmount_lock); |
1624 | rcu_read_lock(); | 1655 | rcu_read_lock(); |
1625 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1656 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
1626 | } else { | 1657 | } else { |
@@ -1633,7 +1664,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1633 | 1664 | ||
1634 | if (*name=='/') { | 1665 | if (*name=='/') { |
1635 | if (flags & LOOKUP_RCU) { | 1666 | if (flags & LOOKUP_RCU) { |
1636 | br_read_lock(vfsmount_lock); | 1667 | br_read_lock(&vfsmount_lock); |
1637 | rcu_read_lock(); | 1668 | rcu_read_lock(); |
1638 | set_root_rcu(nd); | 1669 | set_root_rcu(nd); |
1639 | } else { | 1670 | } else { |
@@ -1646,7 +1677,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1646 | struct fs_struct *fs = current->fs; | 1677 | struct fs_struct *fs = current->fs; |
1647 | unsigned seq; | 1678 | unsigned seq; |
1648 | 1679 | ||
1649 | br_read_lock(vfsmount_lock); | 1680 | br_read_lock(&vfsmount_lock); |
1650 | rcu_read_lock(); | 1681 | rcu_read_lock(); |
1651 | 1682 | ||
1652 | do { | 1683 | do { |
@@ -1682,7 +1713,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
1682 | if (fput_needed) | 1713 | if (fput_needed) |
1683 | *fp = file; | 1714 | *fp = file; |
1684 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1715 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
1685 | br_read_lock(vfsmount_lock); | 1716 | br_read_lock(&vfsmount_lock); |
1686 | rcu_read_lock(); | 1717 | rcu_read_lock(); |
1687 | } else { | 1718 | } else { |
1688 | path_get(&file->f_path); | 1719 | path_get(&file->f_path); |
@@ -2169,6 +2200,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2169 | int want_write = 0; | 2200 | int want_write = 0; |
2170 | int acc_mode = op->acc_mode; | 2201 | int acc_mode = op->acc_mode; |
2171 | struct file *filp; | 2202 | struct file *filp; |
2203 | struct inode *inode; | ||
2204 | int symlink_ok = 0; | ||
2205 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; | ||
2206 | bool retried = false; | ||
2172 | int error; | 2207 | int error; |
2173 | 2208 | ||
2174 | nd->flags &= ~LOOKUP_PARENT; | 2209 | nd->flags &= ~LOOKUP_PARENT; |
@@ -2200,30 +2235,23 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2200 | } | 2235 | } |
2201 | 2236 | ||
2202 | if (!(open_flag & O_CREAT)) { | 2237 | if (!(open_flag & O_CREAT)) { |
2203 | int symlink_ok = 0; | ||
2204 | if (nd->last.name[nd->last.len]) | 2238 | if (nd->last.name[nd->last.len]) |
2205 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; | 2239 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; |
2206 | if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW)) | 2240 | if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW)) |
2207 | symlink_ok = 1; | 2241 | symlink_ok = 1; |
2208 | /* we _can_ be in RCU mode here */ | 2242 | /* we _can_ be in RCU mode here */ |
2209 | error = walk_component(nd, path, &nd->last, LAST_NORM, | 2243 | error = lookup_fast(nd, &nd->last, path, &inode); |
2210 | !symlink_ok); | 2244 | if (unlikely(error)) { |
2211 | if (error < 0) | 2245 | if (error < 0) |
2212 | return ERR_PTR(error); | 2246 | goto exit; |
2213 | if (error) /* symlink */ | ||
2214 | return NULL; | ||
2215 | /* sayonara */ | ||
2216 | error = complete_walk(nd); | ||
2217 | if (error) | ||
2218 | return ERR_PTR(error); | ||
2219 | 2247 | ||
2220 | error = -ENOTDIR; | 2248 | error = lookup_slow(nd, &nd->last, path); |
2221 | if (nd->flags & LOOKUP_DIRECTORY) { | 2249 | if (error < 0) |
2222 | if (!nd->inode->i_op->lookup) | ||
2223 | goto exit; | 2250 | goto exit; |
2251 | |||
2252 | inode = path->dentry->d_inode; | ||
2224 | } | 2253 | } |
2225 | audit_inode(pathname, nd->path.dentry); | 2254 | goto finish_lookup; |
2226 | goto ok; | ||
2227 | } | 2255 | } |
2228 | 2256 | ||
2229 | /* create side of things */ | 2257 | /* create side of things */ |
@@ -2241,6 +2269,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2241 | if (nd->last.name[nd->last.len]) | 2269 | if (nd->last.name[nd->last.len]) |
2242 | goto exit; | 2270 | goto exit; |
2243 | 2271 | ||
2272 | retry_lookup: | ||
2244 | mutex_lock(&dir->d_inode->i_mutex); | 2273 | mutex_lock(&dir->d_inode->i_mutex); |
2245 | 2274 | ||
2246 | dentry = lookup_hash(nd); | 2275 | dentry = lookup_hash(nd); |
@@ -2302,22 +2331,49 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2302 | if (error) | 2331 | if (error) |
2303 | nd->flags |= LOOKUP_JUMPED; | 2332 | nd->flags |= LOOKUP_JUMPED; |
2304 | 2333 | ||
2334 | BUG_ON(nd->flags & LOOKUP_RCU); | ||
2335 | inode = path->dentry->d_inode; | ||
2336 | finish_lookup: | ||
2337 | /* we _can_ be in RCU mode here */ | ||
2305 | error = -ENOENT; | 2338 | error = -ENOENT; |
2306 | if (!path->dentry->d_inode) | 2339 | if (!inode) { |
2307 | goto exit_dput; | 2340 | path_to_nameidata(path, nd); |
2341 | goto exit; | ||
2342 | } | ||
2308 | 2343 | ||
2309 | if (path->dentry->d_inode->i_op->follow_link) | 2344 | if (should_follow_link(inode, !symlink_ok)) { |
2345 | if (nd->flags & LOOKUP_RCU) { | ||
2346 | if (unlikely(unlazy_walk(nd, path->dentry))) { | ||
2347 | error = -ECHILD; | ||
2348 | goto exit; | ||
2349 | } | ||
2350 | } | ||
2351 | BUG_ON(inode != path->dentry->d_inode); | ||
2310 | return NULL; | 2352 | return NULL; |
2353 | } | ||
2311 | 2354 | ||
2312 | path_to_nameidata(path, nd); | 2355 | if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) { |
2313 | nd->inode = path->dentry->d_inode; | 2356 | path_to_nameidata(path, nd); |
2357 | } else { | ||
2358 | save_parent.dentry = nd->path.dentry; | ||
2359 | save_parent.mnt = mntget(path->mnt); | ||
2360 | nd->path.dentry = path->dentry; | ||
2361 | |||
2362 | } | ||
2363 | nd->inode = inode; | ||
2314 | /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ | 2364 | /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ |
2315 | error = complete_walk(nd); | 2365 | error = complete_walk(nd); |
2316 | if (error) | 2366 | if (error) { |
2367 | path_put(&save_parent); | ||
2317 | return ERR_PTR(error); | 2368 | return ERR_PTR(error); |
2369 | } | ||
2318 | error = -EISDIR; | 2370 | error = -EISDIR; |
2319 | if (S_ISDIR(nd->inode->i_mode)) | 2371 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) |
2372 | goto exit; | ||
2373 | error = -ENOTDIR; | ||
2374 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) | ||
2320 | goto exit; | 2375 | goto exit; |
2376 | audit_inode(pathname, nd->path.dentry); | ||
2321 | ok: | 2377 | ok: |
2322 | if (!S_ISREG(nd->inode->i_mode)) | 2378 | if (!S_ISREG(nd->inode->i_mode)) |
2323 | will_truncate = 0; | 2379 | will_truncate = 0; |
@@ -2333,6 +2389,20 @@ common: | |||
2333 | if (error) | 2389 | if (error) |
2334 | goto exit; | 2390 | goto exit; |
2335 | filp = nameidata_to_filp(nd); | 2391 | filp = nameidata_to_filp(nd); |
2392 | if (filp == ERR_PTR(-EOPENSTALE) && save_parent.dentry && !retried) { | ||
2393 | BUG_ON(save_parent.dentry != dir); | ||
2394 | path_put(&nd->path); | ||
2395 | nd->path = save_parent; | ||
2396 | nd->inode = dir->d_inode; | ||
2397 | save_parent.mnt = NULL; | ||
2398 | save_parent.dentry = NULL; | ||
2399 | if (want_write) { | ||
2400 | mnt_drop_write(nd->path.mnt); | ||
2401 | want_write = 0; | ||
2402 | } | ||
2403 | retried = true; | ||
2404 | goto retry_lookup; | ||
2405 | } | ||
2336 | if (!IS_ERR(filp)) { | 2406 | if (!IS_ERR(filp)) { |
2337 | error = ima_file_check(filp, op->acc_mode); | 2407 | error = ima_file_check(filp, op->acc_mode); |
2338 | if (error) { | 2408 | if (error) { |
@@ -2352,7 +2422,8 @@ common: | |||
2352 | out: | 2422 | out: |
2353 | if (want_write) | 2423 | if (want_write) |
2354 | mnt_drop_write(nd->path.mnt); | 2424 | mnt_drop_write(nd->path.mnt); |
2355 | path_put(&nd->path); | 2425 | path_put(&save_parent); |
2426 | terminate_walk(nd); | ||
2356 | return filp; | 2427 | return filp; |
2357 | 2428 | ||
2358 | exit_mutex_unlock: | 2429 | exit_mutex_unlock: |
@@ -2415,6 +2486,12 @@ out: | |||
2415 | if (base) | 2486 | if (base) |
2416 | fput(base); | 2487 | fput(base); |
2417 | release_open_intent(nd); | 2488 | release_open_intent(nd); |
2489 | if (filp == ERR_PTR(-EOPENSTALE)) { | ||
2490 | if (flags & LOOKUP_RCU) | ||
2491 | filp = ERR_PTR(-ECHILD); | ||
2492 | else | ||
2493 | filp = ERR_PTR(-ESTALE); | ||
2494 | } | ||
2418 | return filp; | 2495 | return filp; |
2419 | 2496 | ||
2420 | out_filp: | 2497 | out_filp: |
diff --git a/fs/namespace.c b/fs/namespace.c index e6081996c9a2..1e4a5fe3d7b7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -397,7 +397,7 @@ static int mnt_make_readonly(struct mount *mnt) | |||
397 | { | 397 | { |
398 | int ret = 0; | 398 | int ret = 0; |
399 | 399 | ||
400 | br_write_lock(vfsmount_lock); | 400 | br_write_lock(&vfsmount_lock); |
401 | mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; | 401 | mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; |
402 | /* | 402 | /* |
403 | * After storing MNT_WRITE_HOLD, we'll read the counters. This store | 403 | * After storing MNT_WRITE_HOLD, we'll read the counters. This store |
@@ -431,15 +431,15 @@ static int mnt_make_readonly(struct mount *mnt) | |||
431 | */ | 431 | */ |
432 | smp_wmb(); | 432 | smp_wmb(); |
433 | mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; | 433 | mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; |
434 | br_write_unlock(vfsmount_lock); | 434 | br_write_unlock(&vfsmount_lock); |
435 | return ret; | 435 | return ret; |
436 | } | 436 | } |
437 | 437 | ||
438 | static void __mnt_unmake_readonly(struct mount *mnt) | 438 | static void __mnt_unmake_readonly(struct mount *mnt) |
439 | { | 439 | { |
440 | br_write_lock(vfsmount_lock); | 440 | br_write_lock(&vfsmount_lock); |
441 | mnt->mnt.mnt_flags &= ~MNT_READONLY; | 441 | mnt->mnt.mnt_flags &= ~MNT_READONLY; |
442 | br_write_unlock(vfsmount_lock); | 442 | br_write_unlock(&vfsmount_lock); |
443 | } | 443 | } |
444 | 444 | ||
445 | int sb_prepare_remount_readonly(struct super_block *sb) | 445 | int sb_prepare_remount_readonly(struct super_block *sb) |
@@ -451,7 +451,7 @@ int sb_prepare_remount_readonly(struct super_block *sb) | |||
451 | if (atomic_long_read(&sb->s_remove_count)) | 451 | if (atomic_long_read(&sb->s_remove_count)) |
452 | return -EBUSY; | 452 | return -EBUSY; |
453 | 453 | ||
454 | br_write_lock(vfsmount_lock); | 454 | br_write_lock(&vfsmount_lock); |
455 | list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) { | 455 | list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) { |
456 | if (!(mnt->mnt.mnt_flags & MNT_READONLY)) { | 456 | if (!(mnt->mnt.mnt_flags & MNT_READONLY)) { |
457 | mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; | 457 | mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; |
@@ -473,7 +473,7 @@ int sb_prepare_remount_readonly(struct super_block *sb) | |||
473 | if (mnt->mnt.mnt_flags & MNT_WRITE_HOLD) | 473 | if (mnt->mnt.mnt_flags & MNT_WRITE_HOLD) |
474 | mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; | 474 | mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; |
475 | } | 475 | } |
476 | br_write_unlock(vfsmount_lock); | 476 | br_write_unlock(&vfsmount_lock); |
477 | 477 | ||
478 | return err; | 478 | return err; |
479 | } | 479 | } |
@@ -522,14 +522,14 @@ struct vfsmount *lookup_mnt(struct path *path) | |||
522 | { | 522 | { |
523 | struct mount *child_mnt; | 523 | struct mount *child_mnt; |
524 | 524 | ||
525 | br_read_lock(vfsmount_lock); | 525 | br_read_lock(&vfsmount_lock); |
526 | child_mnt = __lookup_mnt(path->mnt, path->dentry, 1); | 526 | child_mnt = __lookup_mnt(path->mnt, path->dentry, 1); |
527 | if (child_mnt) { | 527 | if (child_mnt) { |
528 | mnt_add_count(child_mnt, 1); | 528 | mnt_add_count(child_mnt, 1); |
529 | br_read_unlock(vfsmount_lock); | 529 | br_read_unlock(&vfsmount_lock); |
530 | return &child_mnt->mnt; | 530 | return &child_mnt->mnt; |
531 | } else { | 531 | } else { |
532 | br_read_unlock(vfsmount_lock); | 532 | br_read_unlock(&vfsmount_lock); |
533 | return NULL; | 533 | return NULL; |
534 | } | 534 | } |
535 | } | 535 | } |
@@ -714,9 +714,9 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
714 | mnt->mnt.mnt_sb = root->d_sb; | 714 | mnt->mnt.mnt_sb = root->d_sb; |
715 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | 715 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; |
716 | mnt->mnt_parent = mnt; | 716 | mnt->mnt_parent = mnt; |
717 | br_write_lock(vfsmount_lock); | 717 | br_write_lock(&vfsmount_lock); |
718 | list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts); | 718 | list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts); |
719 | br_write_unlock(vfsmount_lock); | 719 | br_write_unlock(&vfsmount_lock); |
720 | return &mnt->mnt; | 720 | return &mnt->mnt; |
721 | } | 721 | } |
722 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 722 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
@@ -745,9 +745,9 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
745 | mnt->mnt.mnt_root = dget(root); | 745 | mnt->mnt.mnt_root = dget(root); |
746 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | 746 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; |
747 | mnt->mnt_parent = mnt; | 747 | mnt->mnt_parent = mnt; |
748 | br_write_lock(vfsmount_lock); | 748 | br_write_lock(&vfsmount_lock); |
749 | list_add_tail(&mnt->mnt_instance, &sb->s_mounts); | 749 | list_add_tail(&mnt->mnt_instance, &sb->s_mounts); |
750 | br_write_unlock(vfsmount_lock); | 750 | br_write_unlock(&vfsmount_lock); |
751 | 751 | ||
752 | if (flag & CL_SLAVE) { | 752 | if (flag & CL_SLAVE) { |
753 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); | 753 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); |
@@ -803,35 +803,36 @@ static void mntput_no_expire(struct mount *mnt) | |||
803 | { | 803 | { |
804 | put_again: | 804 | put_again: |
805 | #ifdef CONFIG_SMP | 805 | #ifdef CONFIG_SMP |
806 | br_read_lock(vfsmount_lock); | 806 | br_read_lock(&vfsmount_lock); |
807 | if (likely(atomic_read(&mnt->mnt_longterm))) { | 807 | if (likely(atomic_read(&mnt->mnt_longterm))) { |
808 | mnt_add_count(mnt, -1); | 808 | mnt_add_count(mnt, -1); |
809 | br_read_unlock(vfsmount_lock); | 809 | br_read_unlock(&vfsmount_lock); |
810 | return; | 810 | return; |
811 | } | 811 | } |
812 | br_read_unlock(vfsmount_lock); | 812 | br_read_unlock(&vfsmount_lock); |
813 | 813 | ||
814 | br_write_lock(vfsmount_lock); | 814 | br_write_lock(&vfsmount_lock); |
815 | mnt_add_count(mnt, -1); | 815 | mnt_add_count(mnt, -1); |
816 | if (mnt_get_count(mnt)) { | 816 | if (mnt_get_count(mnt)) { |
817 | br_write_unlock(vfsmount_lock); | 817 | br_write_unlock(&vfsmount_lock); |
818 | return; | 818 | return; |
819 | } | 819 | } |
820 | #else | 820 | #else |
821 | mnt_add_count(mnt, -1); | 821 | mnt_add_count(mnt, -1); |
822 | if (likely(mnt_get_count(mnt))) | 822 | if (likely(mnt_get_count(mnt))) |
823 | return; | 823 | return; |
824 | br_write_lock(vfsmount_lock); | 824 | br_write_lock(&vfsmount_lock); |
825 | #endif | 825 | #endif |
826 | if (unlikely(mnt->mnt_pinned)) { | 826 | if (unlikely(mnt->mnt_pinned)) { |
827 | mnt_add_count(mnt, mnt->mnt_pinned + 1); | 827 | mnt_add_count(mnt, mnt->mnt_pinned + 1); |
828 | mnt->mnt_pinned = 0; | 828 | mnt->mnt_pinned = 0; |
829 | br_write_unlock(vfsmount_lock); | 829 | br_write_unlock(&vfsmount_lock); |
830 | acct_auto_close_mnt(&mnt->mnt); | 830 | acct_auto_close_mnt(&mnt->mnt); |
831 | goto put_again; | 831 | goto put_again; |
832 | } | 832 | } |
833 | |||
833 | list_del(&mnt->mnt_instance); | 834 | list_del(&mnt->mnt_instance); |
834 | br_write_unlock(vfsmount_lock); | 835 | br_write_unlock(&vfsmount_lock); |
835 | mntfree(mnt); | 836 | mntfree(mnt); |
836 | } | 837 | } |
837 | 838 | ||
@@ -857,21 +858,21 @@ EXPORT_SYMBOL(mntget); | |||
857 | 858 | ||
858 | void mnt_pin(struct vfsmount *mnt) | 859 | void mnt_pin(struct vfsmount *mnt) |
859 | { | 860 | { |
860 | br_write_lock(vfsmount_lock); | 861 | br_write_lock(&vfsmount_lock); |
861 | real_mount(mnt)->mnt_pinned++; | 862 | real_mount(mnt)->mnt_pinned++; |
862 | br_write_unlock(vfsmount_lock); | 863 | br_write_unlock(&vfsmount_lock); |
863 | } | 864 | } |
864 | EXPORT_SYMBOL(mnt_pin); | 865 | EXPORT_SYMBOL(mnt_pin); |
865 | 866 | ||
866 | void mnt_unpin(struct vfsmount *m) | 867 | void mnt_unpin(struct vfsmount *m) |
867 | { | 868 | { |
868 | struct mount *mnt = real_mount(m); | 869 | struct mount *mnt = real_mount(m); |
869 | br_write_lock(vfsmount_lock); | 870 | br_write_lock(&vfsmount_lock); |
870 | if (mnt->mnt_pinned) { | 871 | if (mnt->mnt_pinned) { |
871 | mnt_add_count(mnt, 1); | 872 | mnt_add_count(mnt, 1); |
872 | mnt->mnt_pinned--; | 873 | mnt->mnt_pinned--; |
873 | } | 874 | } |
874 | br_write_unlock(vfsmount_lock); | 875 | br_write_unlock(&vfsmount_lock); |
875 | } | 876 | } |
876 | EXPORT_SYMBOL(mnt_unpin); | 877 | EXPORT_SYMBOL(mnt_unpin); |
877 | 878 | ||
@@ -988,12 +989,12 @@ int may_umount_tree(struct vfsmount *m) | |||
988 | BUG_ON(!m); | 989 | BUG_ON(!m); |
989 | 990 | ||
990 | /* write lock needed for mnt_get_count */ | 991 | /* write lock needed for mnt_get_count */ |
991 | br_write_lock(vfsmount_lock); | 992 | br_write_lock(&vfsmount_lock); |
992 | for (p = mnt; p; p = next_mnt(p, mnt)) { | 993 | for (p = mnt; p; p = next_mnt(p, mnt)) { |
993 | actual_refs += mnt_get_count(p); | 994 | actual_refs += mnt_get_count(p); |
994 | minimum_refs += 2; | 995 | minimum_refs += 2; |
995 | } | 996 | } |
996 | br_write_unlock(vfsmount_lock); | 997 | br_write_unlock(&vfsmount_lock); |
997 | 998 | ||
998 | if (actual_refs > minimum_refs) | 999 | if (actual_refs > minimum_refs) |
999 | return 0; | 1000 | return 0; |
@@ -1020,10 +1021,10 @@ int may_umount(struct vfsmount *mnt) | |||
1020 | { | 1021 | { |
1021 | int ret = 1; | 1022 | int ret = 1; |
1022 | down_read(&namespace_sem); | 1023 | down_read(&namespace_sem); |
1023 | br_write_lock(vfsmount_lock); | 1024 | br_write_lock(&vfsmount_lock); |
1024 | if (propagate_mount_busy(real_mount(mnt), 2)) | 1025 | if (propagate_mount_busy(real_mount(mnt), 2)) |
1025 | ret = 0; | 1026 | ret = 0; |
1026 | br_write_unlock(vfsmount_lock); | 1027 | br_write_unlock(&vfsmount_lock); |
1027 | up_read(&namespace_sem); | 1028 | up_read(&namespace_sem); |
1028 | return ret; | 1029 | return ret; |
1029 | } | 1030 | } |
@@ -1040,13 +1041,13 @@ void release_mounts(struct list_head *head) | |||
1040 | struct dentry *dentry; | 1041 | struct dentry *dentry; |
1041 | struct mount *m; | 1042 | struct mount *m; |
1042 | 1043 | ||
1043 | br_write_lock(vfsmount_lock); | 1044 | br_write_lock(&vfsmount_lock); |
1044 | dentry = mnt->mnt_mountpoint; | 1045 | dentry = mnt->mnt_mountpoint; |
1045 | m = mnt->mnt_parent; | 1046 | m = mnt->mnt_parent; |
1046 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | 1047 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; |
1047 | mnt->mnt_parent = mnt; | 1048 | mnt->mnt_parent = mnt; |
1048 | m->mnt_ghosts--; | 1049 | m->mnt_ghosts--; |
1049 | br_write_unlock(vfsmount_lock); | 1050 | br_write_unlock(&vfsmount_lock); |
1050 | dput(dentry); | 1051 | dput(dentry); |
1051 | mntput(&m->mnt); | 1052 | mntput(&m->mnt); |
1052 | } | 1053 | } |
@@ -1073,8 +1074,9 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) | |||
1073 | list_del_init(&p->mnt_expire); | 1074 | list_del_init(&p->mnt_expire); |
1074 | list_del_init(&p->mnt_list); | 1075 | list_del_init(&p->mnt_list); |
1075 | __touch_mnt_namespace(p->mnt_ns); | 1076 | __touch_mnt_namespace(p->mnt_ns); |
1077 | if (p->mnt_ns) | ||
1078 | __mnt_make_shortterm(p); | ||
1076 | p->mnt_ns = NULL; | 1079 | p->mnt_ns = NULL; |
1077 | __mnt_make_shortterm(p); | ||
1078 | list_del_init(&p->mnt_child); | 1080 | list_del_init(&p->mnt_child); |
1079 | if (mnt_has_parent(p)) { | 1081 | if (mnt_has_parent(p)) { |
1080 | p->mnt_parent->mnt_ghosts++; | 1082 | p->mnt_parent->mnt_ghosts++; |
@@ -1112,12 +1114,12 @@ static int do_umount(struct mount *mnt, int flags) | |||
1112 | * probably don't strictly need the lock here if we examined | 1114 | * probably don't strictly need the lock here if we examined |
1113 | * all race cases, but it's a slowpath. | 1115 | * all race cases, but it's a slowpath. |
1114 | */ | 1116 | */ |
1115 | br_write_lock(vfsmount_lock); | 1117 | br_write_lock(&vfsmount_lock); |
1116 | if (mnt_get_count(mnt) != 2) { | 1118 | if (mnt_get_count(mnt) != 2) { |
1117 | br_write_unlock(vfsmount_lock); | 1119 | br_write_unlock(&vfsmount_lock); |
1118 | return -EBUSY; | 1120 | return -EBUSY; |
1119 | } | 1121 | } |
1120 | br_write_unlock(vfsmount_lock); | 1122 | br_write_unlock(&vfsmount_lock); |
1121 | 1123 | ||
1122 | if (!xchg(&mnt->mnt_expiry_mark, 1)) | 1124 | if (!xchg(&mnt->mnt_expiry_mark, 1)) |
1123 | return -EAGAIN; | 1125 | return -EAGAIN; |
@@ -1159,7 +1161,7 @@ static int do_umount(struct mount *mnt, int flags) | |||
1159 | } | 1161 | } |
1160 | 1162 | ||
1161 | down_write(&namespace_sem); | 1163 | down_write(&namespace_sem); |
1162 | br_write_lock(vfsmount_lock); | 1164 | br_write_lock(&vfsmount_lock); |
1163 | event++; | 1165 | event++; |
1164 | 1166 | ||
1165 | if (!(flags & MNT_DETACH)) | 1167 | if (!(flags & MNT_DETACH)) |
@@ -1171,7 +1173,7 @@ static int do_umount(struct mount *mnt, int flags) | |||
1171 | umount_tree(mnt, 1, &umount_list); | 1173 | umount_tree(mnt, 1, &umount_list); |
1172 | retval = 0; | 1174 | retval = 0; |
1173 | } | 1175 | } |
1174 | br_write_unlock(vfsmount_lock); | 1176 | br_write_unlock(&vfsmount_lock); |
1175 | up_write(&namespace_sem); | 1177 | up_write(&namespace_sem); |
1176 | release_mounts(&umount_list); | 1178 | release_mounts(&umount_list); |
1177 | return retval; | 1179 | return retval; |
@@ -1286,19 +1288,19 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1286 | q = clone_mnt(p, p->mnt.mnt_root, flag); | 1288 | q = clone_mnt(p, p->mnt.mnt_root, flag); |
1287 | if (!q) | 1289 | if (!q) |
1288 | goto Enomem; | 1290 | goto Enomem; |
1289 | br_write_lock(vfsmount_lock); | 1291 | br_write_lock(&vfsmount_lock); |
1290 | list_add_tail(&q->mnt_list, &res->mnt_list); | 1292 | list_add_tail(&q->mnt_list, &res->mnt_list); |
1291 | attach_mnt(q, &path); | 1293 | attach_mnt(q, &path); |
1292 | br_write_unlock(vfsmount_lock); | 1294 | br_write_unlock(&vfsmount_lock); |
1293 | } | 1295 | } |
1294 | } | 1296 | } |
1295 | return res; | 1297 | return res; |
1296 | Enomem: | 1298 | Enomem: |
1297 | if (res) { | 1299 | if (res) { |
1298 | LIST_HEAD(umount_list); | 1300 | LIST_HEAD(umount_list); |
1299 | br_write_lock(vfsmount_lock); | 1301 | br_write_lock(&vfsmount_lock); |
1300 | umount_tree(res, 0, &umount_list); | 1302 | umount_tree(res, 0, &umount_list); |
1301 | br_write_unlock(vfsmount_lock); | 1303 | br_write_unlock(&vfsmount_lock); |
1302 | release_mounts(&umount_list); | 1304 | release_mounts(&umount_list); |
1303 | } | 1305 | } |
1304 | return NULL; | 1306 | return NULL; |
@@ -1318,9 +1320,9 @@ void drop_collected_mounts(struct vfsmount *mnt) | |||
1318 | { | 1320 | { |
1319 | LIST_HEAD(umount_list); | 1321 | LIST_HEAD(umount_list); |
1320 | down_write(&namespace_sem); | 1322 | down_write(&namespace_sem); |
1321 | br_write_lock(vfsmount_lock); | 1323 | br_write_lock(&vfsmount_lock); |
1322 | umount_tree(real_mount(mnt), 0, &umount_list); | 1324 | umount_tree(real_mount(mnt), 0, &umount_list); |
1323 | br_write_unlock(vfsmount_lock); | 1325 | br_write_unlock(&vfsmount_lock); |
1324 | up_write(&namespace_sem); | 1326 | up_write(&namespace_sem); |
1325 | release_mounts(&umount_list); | 1327 | release_mounts(&umount_list); |
1326 | } | 1328 | } |
@@ -1448,7 +1450,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, | |||
1448 | if (err) | 1450 | if (err) |
1449 | goto out_cleanup_ids; | 1451 | goto out_cleanup_ids; |
1450 | 1452 | ||
1451 | br_write_lock(vfsmount_lock); | 1453 | br_write_lock(&vfsmount_lock); |
1452 | 1454 | ||
1453 | if (IS_MNT_SHARED(dest_mnt)) { | 1455 | if (IS_MNT_SHARED(dest_mnt)) { |
1454 | for (p = source_mnt; p; p = next_mnt(p, source_mnt)) | 1456 | for (p = source_mnt; p; p = next_mnt(p, source_mnt)) |
@@ -1467,7 +1469,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, | |||
1467 | list_del_init(&child->mnt_hash); | 1469 | list_del_init(&child->mnt_hash); |
1468 | commit_tree(child); | 1470 | commit_tree(child); |
1469 | } | 1471 | } |
1470 | br_write_unlock(vfsmount_lock); | 1472 | br_write_unlock(&vfsmount_lock); |
1471 | 1473 | ||
1472 | return 0; | 1474 | return 0; |
1473 | 1475 | ||
@@ -1565,10 +1567,10 @@ static int do_change_type(struct path *path, int flag) | |||
1565 | goto out_unlock; | 1567 | goto out_unlock; |
1566 | } | 1568 | } |
1567 | 1569 | ||
1568 | br_write_lock(vfsmount_lock); | 1570 | br_write_lock(&vfsmount_lock); |
1569 | for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL)) | 1571 | for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL)) |
1570 | change_mnt_propagation(m, type); | 1572 | change_mnt_propagation(m, type); |
1571 | br_write_unlock(vfsmount_lock); | 1573 | br_write_unlock(&vfsmount_lock); |
1572 | 1574 | ||
1573 | out_unlock: | 1575 | out_unlock: |
1574 | up_write(&namespace_sem); | 1576 | up_write(&namespace_sem); |
@@ -1617,9 +1619,9 @@ static int do_loopback(struct path *path, char *old_name, | |||
1617 | 1619 | ||
1618 | err = graft_tree(mnt, path); | 1620 | err = graft_tree(mnt, path); |
1619 | if (err) { | 1621 | if (err) { |
1620 | br_write_lock(vfsmount_lock); | 1622 | br_write_lock(&vfsmount_lock); |
1621 | umount_tree(mnt, 0, &umount_list); | 1623 | umount_tree(mnt, 0, &umount_list); |
1622 | br_write_unlock(vfsmount_lock); | 1624 | br_write_unlock(&vfsmount_lock); |
1623 | } | 1625 | } |
1624 | out2: | 1626 | out2: |
1625 | unlock_mount(path); | 1627 | unlock_mount(path); |
@@ -1677,16 +1679,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags, | |||
1677 | else | 1679 | else |
1678 | err = do_remount_sb(sb, flags, data, 0); | 1680 | err = do_remount_sb(sb, flags, data, 0); |
1679 | if (!err) { | 1681 | if (!err) { |
1680 | br_write_lock(vfsmount_lock); | 1682 | br_write_lock(&vfsmount_lock); |
1681 | mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; | 1683 | mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; |
1682 | mnt->mnt.mnt_flags = mnt_flags; | 1684 | mnt->mnt.mnt_flags = mnt_flags; |
1683 | br_write_unlock(vfsmount_lock); | 1685 | br_write_unlock(&vfsmount_lock); |
1684 | } | 1686 | } |
1685 | up_write(&sb->s_umount); | 1687 | up_write(&sb->s_umount); |
1686 | if (!err) { | 1688 | if (!err) { |
1687 | br_write_lock(vfsmount_lock); | 1689 | br_write_lock(&vfsmount_lock); |
1688 | touch_mnt_namespace(mnt->mnt_ns); | 1690 | touch_mnt_namespace(mnt->mnt_ns); |
1689 | br_write_unlock(vfsmount_lock); | 1691 | br_write_unlock(&vfsmount_lock); |
1690 | } | 1692 | } |
1691 | return err; | 1693 | return err; |
1692 | } | 1694 | } |
@@ -1893,9 +1895,9 @@ fail: | |||
1893 | /* remove m from any expiration list it may be on */ | 1895 | /* remove m from any expiration list it may be on */ |
1894 | if (!list_empty(&mnt->mnt_expire)) { | 1896 | if (!list_empty(&mnt->mnt_expire)) { |
1895 | down_write(&namespace_sem); | 1897 | down_write(&namespace_sem); |
1896 | br_write_lock(vfsmount_lock); | 1898 | br_write_lock(&vfsmount_lock); |
1897 | list_del_init(&mnt->mnt_expire); | 1899 | list_del_init(&mnt->mnt_expire); |
1898 | br_write_unlock(vfsmount_lock); | 1900 | br_write_unlock(&vfsmount_lock); |
1899 | up_write(&namespace_sem); | 1901 | up_write(&namespace_sem); |
1900 | } | 1902 | } |
1901 | mntput(m); | 1903 | mntput(m); |
@@ -1911,11 +1913,11 @@ fail: | |||
1911 | void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list) | 1913 | void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list) |
1912 | { | 1914 | { |
1913 | down_write(&namespace_sem); | 1915 | down_write(&namespace_sem); |
1914 | br_write_lock(vfsmount_lock); | 1916 | br_write_lock(&vfsmount_lock); |
1915 | 1917 | ||
1916 | list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list); | 1918 | list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list); |
1917 | 1919 | ||
1918 | br_write_unlock(vfsmount_lock); | 1920 | br_write_unlock(&vfsmount_lock); |
1919 | up_write(&namespace_sem); | 1921 | up_write(&namespace_sem); |
1920 | } | 1922 | } |
1921 | EXPORT_SYMBOL(mnt_set_expiry); | 1923 | EXPORT_SYMBOL(mnt_set_expiry); |
@@ -1935,7 +1937,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
1935 | return; | 1937 | return; |
1936 | 1938 | ||
1937 | down_write(&namespace_sem); | 1939 | down_write(&namespace_sem); |
1938 | br_write_lock(vfsmount_lock); | 1940 | br_write_lock(&vfsmount_lock); |
1939 | 1941 | ||
1940 | /* extract from the expiration list every vfsmount that matches the | 1942 | /* extract from the expiration list every vfsmount that matches the |
1941 | * following criteria: | 1943 | * following criteria: |
@@ -1954,7 +1956,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
1954 | touch_mnt_namespace(mnt->mnt_ns); | 1956 | touch_mnt_namespace(mnt->mnt_ns); |
1955 | umount_tree(mnt, 1, &umounts); | 1957 | umount_tree(mnt, 1, &umounts); |
1956 | } | 1958 | } |
1957 | br_write_unlock(vfsmount_lock); | 1959 | br_write_unlock(&vfsmount_lock); |
1958 | up_write(&namespace_sem); | 1960 | up_write(&namespace_sem); |
1959 | 1961 | ||
1960 | release_mounts(&umounts); | 1962 | release_mounts(&umounts); |
@@ -2218,9 +2220,9 @@ void mnt_make_shortterm(struct vfsmount *m) | |||
2218 | struct mount *mnt = real_mount(m); | 2220 | struct mount *mnt = real_mount(m); |
2219 | if (atomic_add_unless(&mnt->mnt_longterm, -1, 1)) | 2221 | if (atomic_add_unless(&mnt->mnt_longterm, -1, 1)) |
2220 | return; | 2222 | return; |
2221 | br_write_lock(vfsmount_lock); | 2223 | br_write_lock(&vfsmount_lock); |
2222 | atomic_dec(&mnt->mnt_longterm); | 2224 | atomic_dec(&mnt->mnt_longterm); |
2223 | br_write_unlock(vfsmount_lock); | 2225 | br_write_unlock(&vfsmount_lock); |
2224 | #endif | 2226 | #endif |
2225 | } | 2227 | } |
2226 | 2228 | ||
@@ -2250,9 +2252,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
2250 | return ERR_PTR(-ENOMEM); | 2252 | return ERR_PTR(-ENOMEM); |
2251 | } | 2253 | } |
2252 | new_ns->root = new; | 2254 | new_ns->root = new; |
2253 | br_write_lock(vfsmount_lock); | 2255 | br_write_lock(&vfsmount_lock); |
2254 | list_add_tail(&new_ns->list, &new->mnt_list); | 2256 | list_add_tail(&new_ns->list, &new->mnt_list); |
2255 | br_write_unlock(vfsmount_lock); | 2257 | br_write_unlock(&vfsmount_lock); |
2256 | 2258 | ||
2257 | /* | 2259 | /* |
2258 | * Second pass: switch the tsk->fs->* elements and mark new vfsmounts | 2260 | * Second pass: switch the tsk->fs->* elements and mark new vfsmounts |
@@ -2416,9 +2418,9 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry, | |||
2416 | int path_is_under(struct path *path1, struct path *path2) | 2418 | int path_is_under(struct path *path1, struct path *path2) |
2417 | { | 2419 | { |
2418 | int res; | 2420 | int res; |
2419 | br_read_lock(vfsmount_lock); | 2421 | br_read_lock(&vfsmount_lock); |
2420 | res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2); | 2422 | res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2); |
2421 | br_read_unlock(vfsmount_lock); | 2423 | br_read_unlock(&vfsmount_lock); |
2422 | return res; | 2424 | return res; |
2423 | } | 2425 | } |
2424 | EXPORT_SYMBOL(path_is_under); | 2426 | EXPORT_SYMBOL(path_is_under); |
@@ -2505,7 +2507,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2505 | /* make sure we can reach put_old from new_root */ | 2507 | /* make sure we can reach put_old from new_root */ |
2506 | if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new)) | 2508 | if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new)) |
2507 | goto out4; | 2509 | goto out4; |
2508 | br_write_lock(vfsmount_lock); | 2510 | br_write_lock(&vfsmount_lock); |
2509 | detach_mnt(new_mnt, &parent_path); | 2511 | detach_mnt(new_mnt, &parent_path); |
2510 | detach_mnt(root_mnt, &root_parent); | 2512 | detach_mnt(root_mnt, &root_parent); |
2511 | /* mount old root on put_old */ | 2513 | /* mount old root on put_old */ |
@@ -2513,7 +2515,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2513 | /* mount new_root on / */ | 2515 | /* mount new_root on / */ |
2514 | attach_mnt(new_mnt, &root_parent); | 2516 | attach_mnt(new_mnt, &root_parent); |
2515 | touch_mnt_namespace(current->nsproxy->mnt_ns); | 2517 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
2516 | br_write_unlock(vfsmount_lock); | 2518 | br_write_unlock(&vfsmount_lock); |
2517 | chroot_fs_refs(&root, &new); | 2519 | chroot_fs_refs(&root, &new); |
2518 | error = 0; | 2520 | error = 0; |
2519 | out4: | 2521 | out4: |
@@ -2576,7 +2578,7 @@ void __init mnt_init(void) | |||
2576 | for (u = 0; u < HASH_SIZE; u++) | 2578 | for (u = 0; u < HASH_SIZE; u++) |
2577 | INIT_LIST_HEAD(&mount_hashtable[u]); | 2579 | INIT_LIST_HEAD(&mount_hashtable[u]); |
2578 | 2580 | ||
2579 | br_lock_init(vfsmount_lock); | 2581 | br_lock_init(&vfsmount_lock); |
2580 | 2582 | ||
2581 | err = sysfs_init(); | 2583 | err = sysfs_init(); |
2582 | if (err) | 2584 | if (err) |
@@ -2596,9 +2598,9 @@ void put_mnt_ns(struct mnt_namespace *ns) | |||
2596 | if (!atomic_dec_and_test(&ns->count)) | 2598 | if (!atomic_dec_and_test(&ns->count)) |
2597 | return; | 2599 | return; |
2598 | down_write(&namespace_sem); | 2600 | down_write(&namespace_sem); |
2599 | br_write_lock(vfsmount_lock); | 2601 | br_write_lock(&vfsmount_lock); |
2600 | umount_tree(ns->root, 0, &umount_list); | 2602 | umount_tree(ns->root, 0, &umount_list); |
2601 | br_write_unlock(vfsmount_lock); | 2603 | br_write_unlock(&vfsmount_lock); |
2602 | up_write(&namespace_sem); | 2604 | up_write(&namespace_sem); |
2603 | release_mounts(&umount_list); | 2605 | release_mounts(&umount_list); |
2604 | kfree(ns); | 2606 | kfree(ns); |
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 3ff5fcc1528f..122e260247f5 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -221,6 +221,10 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t * | |||
221 | 221 | ||
222 | already_written = 0; | 222 | already_written = 0; |
223 | 223 | ||
224 | errno = file_update_time(file); | ||
225 | if (errno) | ||
226 | goto outrel; | ||
227 | |||
224 | bouncebuffer = vmalloc(bufsize); | 228 | bouncebuffer = vmalloc(bufsize); |
225 | if (!bouncebuffer) { | 229 | if (!bouncebuffer) { |
226 | errno = -EIO; /* -ENOMEM */ | 230 | errno = -EIO; /* -ENOMEM */ |
@@ -252,8 +256,6 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t * | |||
252 | } | 256 | } |
253 | vfree(bouncebuffer); | 257 | vfree(bouncebuffer); |
254 | 258 | ||
255 | file_update_time(file); | ||
256 | |||
257 | *ppos = pos; | 259 | *ppos = pos; |
258 | 260 | ||
259 | if (pos > i_size_read(inode)) { | 261 | if (pos > i_size_read(inode)) { |
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h index 4af803f13516..54cc0cdb3dcb 100644 --- a/fs/ncpfs/ncp_fs_sb.h +++ b/fs/ncpfs/ncp_fs_sb.h | |||
@@ -23,17 +23,17 @@ struct ncp_mount_data_kernel { | |||
23 | unsigned long flags; /* NCP_MOUNT_* flags */ | 23 | unsigned long flags; /* NCP_MOUNT_* flags */ |
24 | unsigned int int_flags; /* internal flags */ | 24 | unsigned int int_flags; /* internal flags */ |
25 | #define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 | 25 | #define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 |
26 | __kernel_uid32_t mounted_uid; /* Who may umount() this filesystem? */ | 26 | uid_t mounted_uid; /* Who may umount() this filesystem? */ |
27 | struct pid *wdog_pid; /* Who cares for our watchdog packets? */ | 27 | struct pid *wdog_pid; /* Who cares for our watchdog packets? */ |
28 | unsigned int ncp_fd; /* The socket to the ncp port */ | 28 | unsigned int ncp_fd; /* The socket to the ncp port */ |
29 | unsigned int time_out; /* How long should I wait after | 29 | unsigned int time_out; /* How long should I wait after |
30 | sending a NCP request? */ | 30 | sending a NCP request? */ |
31 | unsigned int retry_count; /* And how often should I retry? */ | 31 | unsigned int retry_count; /* And how often should I retry? */ |
32 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; | 32 | unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; |
33 | __kernel_uid32_t uid; | 33 | uid_t uid; |
34 | __kernel_gid32_t gid; | 34 | gid_t gid; |
35 | __kernel_mode_t file_mode; | 35 | umode_t file_mode; |
36 | __kernel_mode_t dir_mode; | 36 | umode_t dir_mode; |
37 | int info_fd; | 37 | int info_fd; |
38 | }; | 38 | }; |
39 | 39 | ||
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 0989a2099688..f430057ff3b3 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1354,10 +1354,10 @@ out: | |||
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | #ifdef CONFIG_NFS_V4 | 1356 | #ifdef CONFIG_NFS_V4 |
1357 | static int nfs_open_revalidate(struct dentry *, struct nameidata *); | 1357 | static int nfs4_lookup_revalidate(struct dentry *, struct nameidata *); |
1358 | 1358 | ||
1359 | const struct dentry_operations nfs4_dentry_operations = { | 1359 | const struct dentry_operations nfs4_dentry_operations = { |
1360 | .d_revalidate = nfs_open_revalidate, | 1360 | .d_revalidate = nfs4_lookup_revalidate, |
1361 | .d_delete = nfs_dentry_delete, | 1361 | .d_delete = nfs_dentry_delete, |
1362 | .d_iput = nfs_dentry_iput, | 1362 | .d_iput = nfs_dentry_iput, |
1363 | .d_automount = nfs_d_automount, | 1363 | .d_automount = nfs_d_automount, |
@@ -1519,13 +1519,11 @@ no_open: | |||
1519 | return nfs_lookup(dir, dentry, nd); | 1519 | return nfs_lookup(dir, dentry, nd); |
1520 | } | 1520 | } |
1521 | 1521 | ||
1522 | static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | 1522 | static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) |
1523 | { | 1523 | { |
1524 | struct dentry *parent = NULL; | 1524 | struct dentry *parent = NULL; |
1525 | struct inode *inode; | 1525 | struct inode *inode; |
1526 | struct inode *dir; | 1526 | struct inode *dir; |
1527 | struct nfs_open_context *ctx; | ||
1528 | struct iattr attr; | ||
1529 | int openflags, ret = 0; | 1527 | int openflags, ret = 0; |
1530 | 1528 | ||
1531 | if (nd->flags & LOOKUP_RCU) | 1529 | if (nd->flags & LOOKUP_RCU) |
@@ -1554,57 +1552,13 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1554 | /* We cannot do exclusive creation on a positive dentry */ | 1552 | /* We cannot do exclusive creation on a positive dentry */ |
1555 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) | 1553 | if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) |
1556 | goto no_open_dput; | 1554 | goto no_open_dput; |
1557 | /* We can't create new files here */ | ||
1558 | openflags &= ~(O_CREAT|O_EXCL); | ||
1559 | |||
1560 | ctx = create_nfs_open_context(dentry, openflags); | ||
1561 | ret = PTR_ERR(ctx); | ||
1562 | if (IS_ERR(ctx)) | ||
1563 | goto out; | ||
1564 | 1555 | ||
1565 | attr.ia_valid = ATTR_OPEN; | 1556 | /* Let f_op->open() actually open (and revalidate) the file */ |
1566 | if (openflags & O_TRUNC) { | 1557 | ret = 1; |
1567 | attr.ia_valid |= ATTR_SIZE; | ||
1568 | attr.ia_size = 0; | ||
1569 | nfs_wb_all(inode); | ||
1570 | } | ||
1571 | |||
1572 | /* | ||
1573 | * Note: we're not holding inode->i_mutex and so may be racing with | ||
1574 | * operations that change the directory. We therefore save the | ||
1575 | * change attribute *before* we do the RPC call. | ||
1576 | */ | ||
1577 | inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr); | ||
1578 | if (IS_ERR(inode)) { | ||
1579 | ret = PTR_ERR(inode); | ||
1580 | switch (ret) { | ||
1581 | case -EPERM: | ||
1582 | case -EACCES: | ||
1583 | case -EDQUOT: | ||
1584 | case -ENOSPC: | ||
1585 | case -EROFS: | ||
1586 | goto out_put_ctx; | ||
1587 | default: | ||
1588 | goto out_drop; | ||
1589 | } | ||
1590 | } | ||
1591 | iput(inode); | ||
1592 | if (inode != dentry->d_inode) | ||
1593 | goto out_drop; | ||
1594 | 1558 | ||
1595 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | ||
1596 | ret = nfs_intent_set_file(nd, ctx); | ||
1597 | if (ret >= 0) | ||
1598 | ret = 1; | ||
1599 | out: | 1559 | out: |
1600 | dput(parent); | 1560 | dput(parent); |
1601 | return ret; | 1561 | return ret; |
1602 | out_drop: | ||
1603 | d_drop(dentry); | ||
1604 | ret = 0; | ||
1605 | out_put_ctx: | ||
1606 | put_nfs_open_context(ctx); | ||
1607 | goto out; | ||
1608 | 1562 | ||
1609 | no_open_dput: | 1563 | no_open_dput: |
1610 | dput(parent); | 1564 | dput(parent); |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 56311ca5f9f8..a6708e6b438d 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -879,12 +879,81 @@ const struct file_operations nfs_file_operations = { | |||
879 | static int | 879 | static int |
880 | nfs4_file_open(struct inode *inode, struct file *filp) | 880 | nfs4_file_open(struct inode *inode, struct file *filp) |
881 | { | 881 | { |
882 | struct nfs_open_context *ctx; | ||
883 | struct dentry *dentry = filp->f_path.dentry; | ||
884 | struct dentry *parent = NULL; | ||
885 | struct inode *dir; | ||
886 | unsigned openflags = filp->f_flags; | ||
887 | struct iattr attr; | ||
888 | int err; | ||
889 | |||
890 | BUG_ON(inode != dentry->d_inode); | ||
882 | /* | 891 | /* |
883 | * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to | 892 | * If no cached dentry exists or if it's negative, NFSv4 handled the |
884 | * this point, then something is very wrong | 893 | * opens in ->lookup() or ->create(). |
894 | * | ||
895 | * We only get this far for a cached positive dentry. We skipped | ||
896 | * revalidation, so handle it here by dropping the dentry and returning | ||
897 | * -EOPENSTALE. The VFS will retry the lookup/create/open. | ||
885 | */ | 898 | */ |
886 | dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp); | 899 | |
887 | return -ENOTDIR; | 900 | dprintk("NFS: open file(%s/%s)\n", |
901 | dentry->d_parent->d_name.name, | ||
902 | dentry->d_name.name); | ||
903 | |||
904 | if ((openflags & O_ACCMODE) == 3) | ||
905 | openflags--; | ||
906 | |||
907 | /* We can't create new files here */ | ||
908 | openflags &= ~(O_CREAT|O_EXCL); | ||
909 | |||
910 | parent = dget_parent(dentry); | ||
911 | dir = parent->d_inode; | ||
912 | |||
913 | ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); | ||
914 | err = PTR_ERR(ctx); | ||
915 | if (IS_ERR(ctx)) | ||
916 | goto out; | ||
917 | |||
918 | attr.ia_valid = ATTR_OPEN; | ||
919 | if (openflags & O_TRUNC) { | ||
920 | attr.ia_valid |= ATTR_SIZE; | ||
921 | attr.ia_size = 0; | ||
922 | nfs_wb_all(inode); | ||
923 | } | ||
924 | |||
925 | inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr); | ||
926 | if (IS_ERR(inode)) { | ||
927 | err = PTR_ERR(inode); | ||
928 | switch (err) { | ||
929 | case -EPERM: | ||
930 | case -EACCES: | ||
931 | case -EDQUOT: | ||
932 | case -ENOSPC: | ||
933 | case -EROFS: | ||
934 | goto out_put_ctx; | ||
935 | default: | ||
936 | goto out_drop; | ||
937 | } | ||
938 | } | ||
939 | iput(inode); | ||
940 | if (inode != dentry->d_inode) | ||
941 | goto out_drop; | ||
942 | |||
943 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | ||
944 | nfs_file_set_open_context(filp, ctx); | ||
945 | err = 0; | ||
946 | |||
947 | out_put_ctx: | ||
948 | put_nfs_open_context(ctx); | ||
949 | out: | ||
950 | dput(parent); | ||
951 | return err; | ||
952 | |||
953 | out_drop: | ||
954 | d_drop(dentry); | ||
955 | err = -EOPENSTALE; | ||
956 | goto out_put_ctx; | ||
888 | } | 957 | } |
889 | 958 | ||
890 | const struct file_operations nfs4_file_operations = { | 959 | const struct file_operations nfs4_file_operations = { |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 0bb2c2010b95..b72847988b78 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -508,31 +508,29 @@ static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh, | |||
508 | return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen); | 508 | return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen); |
509 | } | 509 | } |
510 | 510 | ||
511 | static int nilfs_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp, | 511 | static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp, |
512 | int connectable) | 512 | struct inode *parent) |
513 | { | 513 | { |
514 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; | 514 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; |
515 | struct inode *inode = dentry->d_inode; | ||
516 | struct nilfs_root *root = NILFS_I(inode)->i_root; | 515 | struct nilfs_root *root = NILFS_I(inode)->i_root; |
517 | int type; | 516 | int type; |
518 | 517 | ||
519 | if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE || | 518 | if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) { |
520 | (connectable && *lenp < NILFS_FID_SIZE_CONNECTABLE)) | 519 | *lenp = NILFS_FID_SIZE_CONNECTABLE; |
520 | return 255; | ||
521 | } | ||
522 | if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) { | ||
523 | *lenp = NILFS_FID_SIZE_NON_CONNECTABLE; | ||
521 | return 255; | 524 | return 255; |
525 | } | ||
522 | 526 | ||
523 | fid->cno = root->cno; | 527 | fid->cno = root->cno; |
524 | fid->ino = inode->i_ino; | 528 | fid->ino = inode->i_ino; |
525 | fid->gen = inode->i_generation; | 529 | fid->gen = inode->i_generation; |
526 | 530 | ||
527 | if (connectable && !S_ISDIR(inode->i_mode)) { | 531 | if (parent) { |
528 | struct inode *parent; | ||
529 | |||
530 | spin_lock(&dentry->d_lock); | ||
531 | parent = dentry->d_parent->d_inode; | ||
532 | fid->parent_ino = parent->i_ino; | 532 | fid->parent_ino = parent->i_ino; |
533 | fid->parent_gen = parent->i_generation; | 533 | fid->parent_gen = parent->i_generation; |
534 | spin_unlock(&dentry->d_lock); | ||
535 | |||
536 | type = FILEID_NILFS_WITH_PARENT; | 534 | type = FILEID_NILFS_WITH_PARENT; |
537 | *lenp = NILFS_FID_SIZE_CONNECTABLE; | 535 | *lenp = NILFS_FID_SIZE_CONNECTABLE; |
538 | } else { | 536 | } else { |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index ccb14d3fc0de..b39c5c161adb 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -123,7 +123,7 @@ int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) | |||
123 | } | 123 | } |
124 | EXPORT_SYMBOL_GPL(__fsnotify_parent); | 124 | EXPORT_SYMBOL_GPL(__fsnotify_parent); |
125 | 125 | ||
126 | static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | 126 | static int send_to_group(struct inode *to_tell, |
127 | struct fsnotify_mark *inode_mark, | 127 | struct fsnotify_mark *inode_mark, |
128 | struct fsnotify_mark *vfsmount_mark, | 128 | struct fsnotify_mark *vfsmount_mark, |
129 | __u32 mask, void *data, | 129 | __u32 mask, void *data, |
@@ -168,10 +168,10 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
168 | vfsmount_test_mask &= ~inode_mark->ignored_mask; | 168 | vfsmount_test_mask &= ~inode_mark->ignored_mask; |
169 | } | 169 | } |
170 | 170 | ||
171 | pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x inode_mark=%p" | 171 | pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p" |
172 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" | 172 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" |
173 | " data=%p data_is=%d cookie=%d event=%p\n", | 173 | " data=%p data_is=%d cookie=%d event=%p\n", |
174 | __func__, group, to_tell, mnt, mask, inode_mark, | 174 | __func__, group, to_tell, mask, inode_mark, |
175 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, | 175 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, |
176 | data_is, cookie, *event); | 176 | data_is, cookie, *event); |
177 | 177 | ||
@@ -258,16 +258,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
258 | 258 | ||
259 | if (inode_group > vfsmount_group) { | 259 | if (inode_group > vfsmount_group) { |
260 | /* handle inode */ | 260 | /* handle inode */ |
261 | ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, | 261 | ret = send_to_group(to_tell, inode_mark, NULL, mask, data, |
262 | data_is, cookie, file_name, &event); | 262 | data_is, cookie, file_name, &event); |
263 | /* we didn't use the vfsmount_mark */ | 263 | /* we didn't use the vfsmount_mark */ |
264 | vfsmount_group = NULL; | 264 | vfsmount_group = NULL; |
265 | } else if (vfsmount_group > inode_group) { | 265 | } else if (vfsmount_group > inode_group) { |
266 | ret = send_to_group(to_tell, &mnt->mnt, NULL, vfsmount_mark, mask, data, | 266 | ret = send_to_group(to_tell, NULL, vfsmount_mark, mask, data, |
267 | data_is, cookie, file_name, &event); | 267 | data_is, cookie, file_name, &event); |
268 | inode_group = NULL; | 268 | inode_group = NULL; |
269 | } else { | 269 | } else { |
270 | ret = send_to_group(to_tell, &mnt->mnt, inode_mark, vfsmount_mark, | 270 | ret = send_to_group(to_tell, inode_mark, vfsmount_mark, |
271 | mask, data, data_is, cookie, file_name, | 271 | mask, data, data_is, cookie, file_name, |
272 | &event); | 272 | &event); |
273 | } | 273 | } |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 8639169221c7..7389d2d5e51d 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -2096,7 +2096,9 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb, | |||
2096 | err = file_remove_suid(file); | 2096 | err = file_remove_suid(file); |
2097 | if (err) | 2097 | if (err) |
2098 | goto out; | 2098 | goto out; |
2099 | file_update_time(file); | 2099 | err = file_update_time(file); |
2100 | if (err) | ||
2101 | goto out; | ||
2100 | written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos, | 2102 | written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos, |
2101 | count); | 2103 | count); |
2102 | out: | 2104 | out: |
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index c7ee03c22226..0725e6054650 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c | |||
@@ -422,45 +422,46 @@ int ocfs2_block_check_validate(void *data, size_t blocksize, | |||
422 | struct ocfs2_blockcheck_stats *stats) | 422 | struct ocfs2_blockcheck_stats *stats) |
423 | { | 423 | { |
424 | int rc = 0; | 424 | int rc = 0; |
425 | struct ocfs2_block_check check; | 425 | u32 bc_crc32e; |
426 | u16 bc_ecc; | ||
426 | u32 crc, ecc; | 427 | u32 crc, ecc; |
427 | 428 | ||
428 | ocfs2_blockcheck_inc_check(stats); | 429 | ocfs2_blockcheck_inc_check(stats); |
429 | 430 | ||
430 | check.bc_crc32e = le32_to_cpu(bc->bc_crc32e); | 431 | bc_crc32e = le32_to_cpu(bc->bc_crc32e); |
431 | check.bc_ecc = le16_to_cpu(bc->bc_ecc); | 432 | bc_ecc = le16_to_cpu(bc->bc_ecc); |
432 | 433 | ||
433 | memset(bc, 0, sizeof(struct ocfs2_block_check)); | 434 | memset(bc, 0, sizeof(struct ocfs2_block_check)); |
434 | 435 | ||
435 | /* Fast path - if the crc32 validates, we're good to go */ | 436 | /* Fast path - if the crc32 validates, we're good to go */ |
436 | crc = crc32_le(~0, data, blocksize); | 437 | crc = crc32_le(~0, data, blocksize); |
437 | if (crc == check.bc_crc32e) | 438 | if (crc == bc_crc32e) |
438 | goto out; | 439 | goto out; |
439 | 440 | ||
440 | ocfs2_blockcheck_inc_failure(stats); | 441 | ocfs2_blockcheck_inc_failure(stats); |
441 | mlog(ML_ERROR, | 442 | mlog(ML_ERROR, |
442 | "CRC32 failed: stored: 0x%x, computed 0x%x. Applying ECC.\n", | 443 | "CRC32 failed: stored: 0x%x, computed 0x%x. Applying ECC.\n", |
443 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 444 | (unsigned int)bc_crc32e, (unsigned int)crc); |
444 | 445 | ||
445 | /* Ok, try ECC fixups */ | 446 | /* Ok, try ECC fixups */ |
446 | ecc = ocfs2_hamming_encode_block(data, blocksize); | 447 | ecc = ocfs2_hamming_encode_block(data, blocksize); |
447 | ocfs2_hamming_fix_block(data, blocksize, ecc ^ check.bc_ecc); | 448 | ocfs2_hamming_fix_block(data, blocksize, ecc ^ bc_ecc); |
448 | 449 | ||
449 | /* And check the crc32 again */ | 450 | /* And check the crc32 again */ |
450 | crc = crc32_le(~0, data, blocksize); | 451 | crc = crc32_le(~0, data, blocksize); |
451 | if (crc == check.bc_crc32e) { | 452 | if (crc == bc_crc32e) { |
452 | ocfs2_blockcheck_inc_recover(stats); | 453 | ocfs2_blockcheck_inc_recover(stats); |
453 | goto out; | 454 | goto out; |
454 | } | 455 | } |
455 | 456 | ||
456 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: 0x%x, computed 0x%x\n", | 457 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: 0x%x, computed 0x%x\n", |
457 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 458 | (unsigned int)bc_crc32e, (unsigned int)crc); |
458 | 459 | ||
459 | rc = -EIO; | 460 | rc = -EIO; |
460 | 461 | ||
461 | out: | 462 | out: |
462 | bc->bc_crc32e = cpu_to_le32(check.bc_crc32e); | 463 | bc->bc_crc32e = cpu_to_le32(bc_crc32e); |
463 | bc->bc_ecc = cpu_to_le16(check.bc_ecc); | 464 | bc->bc_ecc = cpu_to_le16(bc_ecc); |
464 | 465 | ||
465 | return rc; | 466 | return rc; |
466 | } | 467 | } |
@@ -528,7 +529,8 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, | |||
528 | struct ocfs2_blockcheck_stats *stats) | 529 | struct ocfs2_blockcheck_stats *stats) |
529 | { | 530 | { |
530 | int i, rc = 0; | 531 | int i, rc = 0; |
531 | struct ocfs2_block_check check; | 532 | u32 bc_crc32e; |
533 | u16 bc_ecc; | ||
532 | u32 crc, ecc, fix; | 534 | u32 crc, ecc, fix; |
533 | 535 | ||
534 | BUG_ON(nr < 0); | 536 | BUG_ON(nr < 0); |
@@ -538,21 +540,21 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, | |||
538 | 540 | ||
539 | ocfs2_blockcheck_inc_check(stats); | 541 | ocfs2_blockcheck_inc_check(stats); |
540 | 542 | ||
541 | check.bc_crc32e = le32_to_cpu(bc->bc_crc32e); | 543 | bc_crc32e = le32_to_cpu(bc->bc_crc32e); |
542 | check.bc_ecc = le16_to_cpu(bc->bc_ecc); | 544 | bc_ecc = le16_to_cpu(bc->bc_ecc); |
543 | 545 | ||
544 | memset(bc, 0, sizeof(struct ocfs2_block_check)); | 546 | memset(bc, 0, sizeof(struct ocfs2_block_check)); |
545 | 547 | ||
546 | /* Fast path - if the crc32 validates, we're good to go */ | 548 | /* Fast path - if the crc32 validates, we're good to go */ |
547 | for (i = 0, crc = ~0; i < nr; i++) | 549 | for (i = 0, crc = ~0; i < nr; i++) |
548 | crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size); | 550 | crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size); |
549 | if (crc == check.bc_crc32e) | 551 | if (crc == bc_crc32e) |
550 | goto out; | 552 | goto out; |
551 | 553 | ||
552 | ocfs2_blockcheck_inc_failure(stats); | 554 | ocfs2_blockcheck_inc_failure(stats); |
553 | mlog(ML_ERROR, | 555 | mlog(ML_ERROR, |
554 | "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", | 556 | "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", |
555 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 557 | (unsigned int)bc_crc32e, (unsigned int)crc); |
556 | 558 | ||
557 | /* Ok, try ECC fixups */ | 559 | /* Ok, try ECC fixups */ |
558 | for (i = 0, ecc = 0; i < nr; i++) { | 560 | for (i = 0, ecc = 0; i < nr; i++) { |
@@ -565,7 +567,7 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, | |||
565 | bhs[i]->b_size * 8, | 567 | bhs[i]->b_size * 8, |
566 | bhs[i]->b_size * 8 * i); | 568 | bhs[i]->b_size * 8 * i); |
567 | } | 569 | } |
568 | fix = ecc ^ check.bc_ecc; | 570 | fix = ecc ^ bc_ecc; |
569 | for (i = 0; i < nr; i++) { | 571 | for (i = 0; i < nr; i++) { |
570 | /* | 572 | /* |
571 | * Try the fix against each buffer. It will only affect | 573 | * Try the fix against each buffer. It will only affect |
@@ -578,19 +580,19 @@ int ocfs2_block_check_validate_bhs(struct buffer_head **bhs, int nr, | |||
578 | /* And check the crc32 again */ | 580 | /* And check the crc32 again */ |
579 | for (i = 0, crc = ~0; i < nr; i++) | 581 | for (i = 0, crc = ~0; i < nr; i++) |
580 | crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size); | 582 | crc = crc32_le(crc, bhs[i]->b_data, bhs[i]->b_size); |
581 | if (crc == check.bc_crc32e) { | 583 | if (crc == bc_crc32e) { |
582 | ocfs2_blockcheck_inc_recover(stats); | 584 | ocfs2_blockcheck_inc_recover(stats); |
583 | goto out; | 585 | goto out; |
584 | } | 586 | } |
585 | 587 | ||
586 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", | 588 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", |
587 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 589 | (unsigned int)bc_crc32e, (unsigned int)crc); |
588 | 590 | ||
589 | rc = -EIO; | 591 | rc = -EIO; |
590 | 592 | ||
591 | out: | 593 | out: |
592 | bc->bc_crc32e = cpu_to_le32(check.bc_crc32e); | 594 | bc->bc_crc32e = cpu_to_le32(bc_crc32e); |
593 | bc->bc_ecc = cpu_to_le16(check.bc_ecc); | 595 | bc->bc_ecc = cpu_to_le16(bc_ecc); |
594 | 596 | ||
595 | return rc; | 597 | return rc; |
596 | } | 598 | } |
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index 3a3ed4bb794b..fbec0be62326 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c | |||
@@ -293,7 +293,7 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, | |||
293 | struct dlm_proxy_ast *past = (struct dlm_proxy_ast *) msg->buf; | 293 | struct dlm_proxy_ast *past = (struct dlm_proxy_ast *) msg->buf; |
294 | char *name; | 294 | char *name; |
295 | struct list_head *iter, *head=NULL; | 295 | struct list_head *iter, *head=NULL; |
296 | u64 cookie; | 296 | __be64 cookie; |
297 | u32 flags; | 297 | u32 flags; |
298 | u8 node; | 298 | u8 node; |
299 | 299 | ||
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index a5952ceecba5..de854cca12a2 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -679,7 +679,7 @@ struct dlm_query_join_packet { | |||
679 | }; | 679 | }; |
680 | 680 | ||
681 | union dlm_query_join_response { | 681 | union dlm_query_join_response { |
682 | u32 intval; | 682 | __be32 intval; |
683 | struct dlm_query_join_packet packet; | 683 | struct dlm_query_join_packet packet; |
684 | }; | 684 | }; |
685 | 685 | ||
@@ -755,8 +755,8 @@ struct dlm_query_region { | |||
755 | struct dlm_node_info { | 755 | struct dlm_node_info { |
756 | u8 ni_nodenum; | 756 | u8 ni_nodenum; |
757 | u8 pad1; | 757 | u8 pad1; |
758 | u16 ni_ipv4_port; | 758 | __be16 ni_ipv4_port; |
759 | u32 ni_ipv4_address; | 759 | __be32 ni_ipv4_address; |
760 | }; | 760 | }; |
761 | 761 | ||
762 | struct dlm_query_nodeinfo { | 762 | struct dlm_query_nodeinfo { |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 92f2ead0fab6..9e89d70df337 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -818,7 +818,7 @@ static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet, | |||
818 | union dlm_query_join_response response; | 818 | union dlm_query_join_response response; |
819 | 819 | ||
820 | response.packet = *packet; | 820 | response.packet = *packet; |
821 | *wire = cpu_to_be32(response.intval); | 821 | *wire = be32_to_cpu(response.intval); |
822 | } | 822 | } |
823 | 823 | ||
824 | static void dlm_query_join_wire_to_packet(u32 wire, | 824 | static void dlm_query_join_wire_to_packet(u32 wire, |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index 745db42528d5..322216a5f0dd 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -177,21 +177,23 @@ bail: | |||
177 | return parent; | 177 | return parent; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, | 180 | static int ocfs2_encode_fh(struct inode *inode, u32 *fh_in, int *max_len, |
181 | int connectable) | 181 | struct inode *parent) |
182 | { | 182 | { |
183 | struct inode *inode = dentry->d_inode; | ||
184 | int len = *max_len; | 183 | int len = *max_len; |
185 | int type = 1; | 184 | int type = 1; |
186 | u64 blkno; | 185 | u64 blkno; |
187 | u32 generation; | 186 | u32 generation; |
188 | __le32 *fh = (__force __le32 *) fh_in; | 187 | __le32 *fh = (__force __le32 *) fh_in; |
189 | 188 | ||
189 | #ifdef TRACE_HOOKS_ARE_NOT_BRAINDEAD_IN_YOUR_OPINION | ||
190 | #error "You go ahead and fix that mess, then. Somehow" | ||
190 | trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, | 191 | trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len, |
191 | dentry->d_name.name, | 192 | dentry->d_name.name, |
192 | fh, len, connectable); | 193 | fh, len, connectable); |
194 | #endif | ||
193 | 195 | ||
194 | if (connectable && (len < 6)) { | 196 | if (parent && (len < 6)) { |
195 | *max_len = 6; | 197 | *max_len = 6; |
196 | type = 255; | 198 | type = 255; |
197 | goto bail; | 199 | goto bail; |
@@ -211,12 +213,7 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, | |||
211 | fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff)); | 213 | fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff)); |
212 | fh[2] = cpu_to_le32(generation); | 214 | fh[2] = cpu_to_le32(generation); |
213 | 215 | ||
214 | if (connectable && !S_ISDIR(inode->i_mode)) { | 216 | if (parent) { |
215 | struct inode *parent; | ||
216 | |||
217 | spin_lock(&dentry->d_lock); | ||
218 | |||
219 | parent = dentry->d_parent->d_inode; | ||
220 | blkno = OCFS2_I(parent)->ip_blkno; | 217 | blkno = OCFS2_I(parent)->ip_blkno; |
221 | generation = parent->i_generation; | 218 | generation = parent->i_generation; |
222 | 219 | ||
@@ -224,8 +221,6 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, | |||
224 | fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff)); | 221 | fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff)); |
225 | fh[5] = cpu_to_le32(generation); | 222 | fh[5] = cpu_to_le32(generation); |
226 | 223 | ||
227 | spin_unlock(&dentry->d_lock); | ||
228 | |||
229 | len = 6; | 224 | len = 6; |
230 | type = 2; | 225 | type = 2; |
231 | 226 | ||
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 735514ca400f..d89e08a81eda 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -273,11 +273,13 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
273 | inode->i_gid = le32_to_cpu(fe->i_gid); | 273 | inode->i_gid = le32_to_cpu(fe->i_gid); |
274 | 274 | ||
275 | /* Fast symlinks will have i_size but no allocated clusters. */ | 275 | /* Fast symlinks will have i_size but no allocated clusters. */ |
276 | if (S_ISLNK(inode->i_mode) && !fe->i_clusters) | 276 | if (S_ISLNK(inode->i_mode) && !fe->i_clusters) { |
277 | inode->i_blocks = 0; | 277 | inode->i_blocks = 0; |
278 | else | 278 | inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops; |
279 | } else { | ||
279 | inode->i_blocks = ocfs2_inode_sector_count(inode); | 280 | inode->i_blocks = ocfs2_inode_sector_count(inode); |
280 | inode->i_mapping->a_ops = &ocfs2_aops; | 281 | inode->i_mapping->a_ops = &ocfs2_aops; |
282 | } | ||
281 | inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime); | 283 | inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime); |
282 | inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec); | 284 | inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec); |
283 | inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime); | 285 | inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime); |
@@ -331,10 +333,7 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
331 | OCFS2_I(inode)->ip_dir_lock_gen = 1; | 333 | OCFS2_I(inode)->ip_dir_lock_gen = 1; |
332 | break; | 334 | break; |
333 | case S_IFLNK: | 335 | case S_IFLNK: |
334 | if (ocfs2_inode_is_fast_symlink(inode)) | 336 | inode->i_op = &ocfs2_symlink_inode_operations; |
335 | inode->i_op = &ocfs2_fast_symlink_inode_operations; | ||
336 | else | ||
337 | inode->i_op = &ocfs2_symlink_inode_operations; | ||
338 | i_size_write(inode, le64_to_cpu(fe->i_size)); | 337 | i_size_write(inode, le64_to_cpu(fe->i_size)); |
339 | break; | 338 | break; |
340 | default: | 339 | default: |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index a1a1bfd652c9..d96f7f81d8dd 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -864,7 +864,7 @@ int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info, | |||
864 | if (status) | 864 | if (status) |
865 | break; | 865 | break; |
866 | 866 | ||
867 | reqp = (struct ocfs2_info_request *)(unsigned long)req_addr; | 867 | reqp = (struct ocfs2_info_request __user *)(unsigned long)req_addr; |
868 | if (!reqp) { | 868 | if (!reqp) { |
869 | status = -EINVAL; | 869 | status = -EINVAL; |
870 | goto bail; | 870 | goto bail; |
@@ -888,9 +888,11 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
888 | struct ocfs2_space_resv sr; | 888 | struct ocfs2_space_resv sr; |
889 | struct ocfs2_new_group_input input; | 889 | struct ocfs2_new_group_input input; |
890 | struct reflink_arguments args; | 890 | struct reflink_arguments args; |
891 | const char *old_path, *new_path; | 891 | const char __user *old_path; |
892 | const char __user *new_path; | ||
892 | bool preserve; | 893 | bool preserve; |
893 | struct ocfs2_info info; | 894 | struct ocfs2_info info; |
895 | void __user *argp = (void __user *)arg; | ||
894 | 896 | ||
895 | switch (cmd) { | 897 | switch (cmd) { |
896 | case OCFS2_IOC_GETFLAGS: | 898 | case OCFS2_IOC_GETFLAGS: |
@@ -937,17 +939,15 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
937 | 939 | ||
938 | return ocfs2_group_add(inode, &input); | 940 | return ocfs2_group_add(inode, &input); |
939 | case OCFS2_IOC_REFLINK: | 941 | case OCFS2_IOC_REFLINK: |
940 | if (copy_from_user(&args, (struct reflink_arguments *)arg, | 942 | if (copy_from_user(&args, argp, sizeof(args))) |
941 | sizeof(args))) | ||
942 | return -EFAULT; | 943 | return -EFAULT; |
943 | old_path = (const char *)(unsigned long)args.old_path; | 944 | old_path = (const char __user *)(unsigned long)args.old_path; |
944 | new_path = (const char *)(unsigned long)args.new_path; | 945 | new_path = (const char __user *)(unsigned long)args.new_path; |
945 | preserve = (args.preserve != 0); | 946 | preserve = (args.preserve != 0); |
946 | 947 | ||
947 | return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve); | 948 | return ocfs2_reflink_ioctl(inode, old_path, new_path, preserve); |
948 | case OCFS2_IOC_INFO: | 949 | case OCFS2_IOC_INFO: |
949 | if (copy_from_user(&info, (struct ocfs2_info __user *)arg, | 950 | if (copy_from_user(&info, argp, sizeof(struct ocfs2_info))) |
950 | sizeof(struct ocfs2_info))) | ||
951 | return -EFAULT; | 951 | return -EFAULT; |
952 | 952 | ||
953 | return ocfs2_info_handle(inode, &info, 0); | 953 | return ocfs2_info_handle(inode, &info, 0); |
@@ -960,22 +960,20 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
960 | if (!capable(CAP_SYS_ADMIN)) | 960 | if (!capable(CAP_SYS_ADMIN)) |
961 | return -EPERM; | 961 | return -EPERM; |
962 | 962 | ||
963 | if (copy_from_user(&range, (struct fstrim_range *)arg, | 963 | if (copy_from_user(&range, argp, sizeof(range))) |
964 | sizeof(range))) | ||
965 | return -EFAULT; | 964 | return -EFAULT; |
966 | 965 | ||
967 | ret = ocfs2_trim_fs(sb, &range); | 966 | ret = ocfs2_trim_fs(sb, &range); |
968 | if (ret < 0) | 967 | if (ret < 0) |
969 | return ret; | 968 | return ret; |
970 | 969 | ||
971 | if (copy_to_user((struct fstrim_range *)arg, &range, | 970 | if (copy_to_user(argp, &range, sizeof(range))) |
972 | sizeof(range))) | ||
973 | return -EFAULT; | 971 | return -EFAULT; |
974 | 972 | ||
975 | return 0; | 973 | return 0; |
976 | } | 974 | } |
977 | case OCFS2_IOC_MOVE_EXT: | 975 | case OCFS2_IOC_MOVE_EXT: |
978 | return ocfs2_ioctl_move_extents(filp, (void __user *)arg); | 976 | return ocfs2_ioctl_move_extents(filp, argp); |
979 | default: | 977 | default: |
980 | return -ENOTTY; | 978 | return -ENOTTY; |
981 | } | 979 | } |
@@ -988,6 +986,7 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
988 | struct reflink_arguments args; | 986 | struct reflink_arguments args; |
989 | struct inode *inode = file->f_path.dentry->d_inode; | 987 | struct inode *inode = file->f_path.dentry->d_inode; |
990 | struct ocfs2_info info; | 988 | struct ocfs2_info info; |
989 | void __user *argp = (void __user *)arg; | ||
991 | 990 | ||
992 | switch (cmd) { | 991 | switch (cmd) { |
993 | case OCFS2_IOC32_GETFLAGS: | 992 | case OCFS2_IOC32_GETFLAGS: |
@@ -1006,16 +1005,14 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1006 | case FITRIM: | 1005 | case FITRIM: |
1007 | break; | 1006 | break; |
1008 | case OCFS2_IOC_REFLINK: | 1007 | case OCFS2_IOC_REFLINK: |
1009 | if (copy_from_user(&args, (struct reflink_arguments *)arg, | 1008 | if (copy_from_user(&args, argp, sizeof(args))) |
1010 | sizeof(args))) | ||
1011 | return -EFAULT; | 1009 | return -EFAULT; |
1012 | preserve = (args.preserve != 0); | 1010 | preserve = (args.preserve != 0); |
1013 | 1011 | ||
1014 | return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path), | 1012 | return ocfs2_reflink_ioctl(inode, compat_ptr(args.old_path), |
1015 | compat_ptr(args.new_path), preserve); | 1013 | compat_ptr(args.new_path), preserve); |
1016 | case OCFS2_IOC_INFO: | 1014 | case OCFS2_IOC_INFO: |
1017 | if (copy_from_user(&info, (struct ocfs2_info __user *)arg, | 1015 | if (copy_from_user(&info, argp, sizeof(struct ocfs2_info))) |
1018 | sizeof(struct ocfs2_info))) | ||
1019 | return -EFAULT; | 1016 | return -EFAULT; |
1020 | 1017 | ||
1021 | return ocfs2_info_handle(inode, &info, 1); | 1018 | return ocfs2_info_handle(inode, &info, 1); |
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index b1e3fce72ea4..6083432f667e 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -1082,8 +1082,7 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) | |||
1082 | context->file = filp; | 1082 | context->file = filp; |
1083 | 1083 | ||
1084 | if (argp) { | 1084 | if (argp) { |
1085 | if (copy_from_user(&range, (struct ocfs2_move_extents *)argp, | 1085 | if (copy_from_user(&range, argp, sizeof(range))) { |
1086 | sizeof(range))) { | ||
1087 | status = -EFAULT; | 1086 | status = -EFAULT; |
1088 | goto out; | 1087 | goto out; |
1089 | } | 1088 | } |
@@ -1138,8 +1137,7 @@ out: | |||
1138 | * length and new_offset even if failure happens somewhere. | 1137 | * length and new_offset even if failure happens somewhere. |
1139 | */ | 1138 | */ |
1140 | if (argp) { | 1139 | if (argp) { |
1141 | if (copy_to_user((struct ocfs2_move_extents *)argp, &range, | 1140 | if (copy_to_user(argp, &range, sizeof(range))) |
1142 | sizeof(range))) | ||
1143 | status = -EFAULT; | 1141 | status = -EFAULT; |
1144 | } | 1142 | } |
1145 | 1143 | ||
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a9856e3eaaf0..9f39c640cddf 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -1724,15 +1724,16 @@ static int ocfs2_symlink(struct inode *dir, | |||
1724 | fe = (struct ocfs2_dinode *) new_fe_bh->b_data; | 1724 | fe = (struct ocfs2_dinode *) new_fe_bh->b_data; |
1725 | inode->i_rdev = 0; | 1725 | inode->i_rdev = 0; |
1726 | newsize = l - 1; | 1726 | newsize = l - 1; |
1727 | inode->i_op = &ocfs2_symlink_inode_operations; | ||
1727 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1728 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1728 | u32 offset = 0; | 1729 | u32 offset = 0; |
1729 | 1730 | ||
1730 | inode->i_op = &ocfs2_symlink_inode_operations; | ||
1731 | status = dquot_alloc_space_nodirty(inode, | 1731 | status = dquot_alloc_space_nodirty(inode, |
1732 | ocfs2_clusters_to_bytes(osb->sb, 1)); | 1732 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
1733 | if (status) | 1733 | if (status) |
1734 | goto bail; | 1734 | goto bail; |
1735 | did_quota = 1; | 1735 | did_quota = 1; |
1736 | inode->i_mapping->a_ops = &ocfs2_aops; | ||
1736 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, | 1737 | status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0, |
1737 | new_fe_bh, | 1738 | new_fe_bh, |
1738 | handle, data_ac, NULL, | 1739 | handle, data_ac, NULL, |
@@ -1750,7 +1751,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1750 | i_size_write(inode, newsize); | 1751 | i_size_write(inode, newsize); |
1751 | inode->i_blocks = ocfs2_inode_sector_count(inode); | 1752 | inode->i_blocks = ocfs2_inode_sector_count(inode); |
1752 | } else { | 1753 | } else { |
1753 | inode->i_op = &ocfs2_fast_symlink_inode_operations; | 1754 | inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops; |
1754 | memcpy((char *) fe->id2.i_symlink, symname, l); | 1755 | memcpy((char *) fe->id2.i_symlink, symname, l); |
1755 | i_size_write(inode, newsize); | 1756 | i_size_write(inode, newsize); |
1756 | inode->i_blocks = 0; | 1757 | inode->i_blocks = 0; |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 5d22872e2bb3..f1fbb4b552ad 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -54,101 +54,40 @@ | |||
54 | #include "buffer_head_io.h" | 54 | #include "buffer_head_io.h" |
55 | 55 | ||
56 | 56 | ||
57 | static char *ocfs2_fast_symlink_getlink(struct inode *inode, | 57 | static int ocfs2_fast_symlink_readpage(struct file *unused, struct page *page) |
58 | struct buffer_head **bh) | ||
59 | { | 58 | { |
60 | int status; | 59 | struct inode *inode = page->mapping->host; |
61 | char *link = NULL; | 60 | struct buffer_head *bh; |
61 | int status = ocfs2_read_inode_block(inode, &bh); | ||
62 | struct ocfs2_dinode *fe; | 62 | struct ocfs2_dinode *fe; |
63 | const char *link; | ||
64 | void *kaddr; | ||
65 | size_t len; | ||
63 | 66 | ||
64 | status = ocfs2_read_inode_block(inode, bh); | ||
65 | if (status < 0) { | 67 | if (status < 0) { |
66 | mlog_errno(status); | 68 | mlog_errno(status); |
67 | link = ERR_PTR(status); | 69 | return status; |
68 | goto bail; | ||
69 | } | 70 | } |
70 | 71 | ||
71 | fe = (struct ocfs2_dinode *) (*bh)->b_data; | 72 | fe = (struct ocfs2_dinode *) bh->b_data; |
72 | link = (char *) fe->id2.i_symlink; | 73 | link = (char *) fe->id2.i_symlink; |
73 | bail: | 74 | /* will be less than a page size */ |
74 | 75 | len = strnlen(link, ocfs2_fast_symlink_chars(inode->i_sb)); | |
75 | return link; | 76 | kaddr = kmap_atomic(page); |
76 | } | 77 | memcpy(kaddr, link, len + 1); |
77 | 78 | kunmap_atomic(kaddr); | |
78 | static int ocfs2_readlink(struct dentry *dentry, | 79 | SetPageUptodate(page); |
79 | char __user *buffer, | 80 | unlock_page(page); |
80 | int buflen) | ||
81 | { | ||
82 | int ret; | ||
83 | char *link; | ||
84 | struct buffer_head *bh = NULL; | ||
85 | struct inode *inode = dentry->d_inode; | ||
86 | |||
87 | link = ocfs2_fast_symlink_getlink(inode, &bh); | ||
88 | if (IS_ERR(link)) { | ||
89 | ret = PTR_ERR(link); | ||
90 | goto out; | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Without vfsmount we can't update atime now, | ||
95 | * but we will update atime here ultimately. | ||
96 | */ | ||
97 | ret = vfs_readlink(dentry, buffer, buflen, link); | ||
98 | |||
99 | brelse(bh); | 81 | brelse(bh); |
100 | out: | 82 | return 0; |
101 | if (ret < 0) | ||
102 | mlog_errno(ret); | ||
103 | return ret; | ||
104 | } | 83 | } |
105 | 84 | ||
106 | static void *ocfs2_fast_follow_link(struct dentry *dentry, | 85 | const struct address_space_operations ocfs2_fast_symlink_aops = { |
107 | struct nameidata *nd) | 86 | .readpage = ocfs2_fast_symlink_readpage, |
108 | { | 87 | }; |
109 | int status = 0; | ||
110 | int len; | ||
111 | char *target, *link = ERR_PTR(-ENOMEM); | ||
112 | struct inode *inode = dentry->d_inode; | ||
113 | struct buffer_head *bh = NULL; | ||
114 | |||
115 | BUG_ON(!ocfs2_inode_is_fast_symlink(inode)); | ||
116 | target = ocfs2_fast_symlink_getlink(inode, &bh); | ||
117 | if (IS_ERR(target)) { | ||
118 | status = PTR_ERR(target); | ||
119 | mlog_errno(status); | ||
120 | goto bail; | ||
121 | } | ||
122 | |||
123 | /* Fast symlinks can't be large */ | ||
124 | len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb)); | ||
125 | link = kzalloc(len + 1, GFP_NOFS); | ||
126 | if (!link) { | ||
127 | status = -ENOMEM; | ||
128 | mlog_errno(status); | ||
129 | goto bail; | ||
130 | } | ||
131 | |||
132 | memcpy(link, target, len); | ||
133 | |||
134 | bail: | ||
135 | nd_set_link(nd, status ? ERR_PTR(status) : link); | ||
136 | brelse(bh); | ||
137 | |||
138 | if (status) | ||
139 | mlog_errno(status); | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | static void ocfs2_fast_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | ||
144 | { | ||
145 | char *link = nd_get_link(nd); | ||
146 | if (!IS_ERR(link)) | ||
147 | kfree(link); | ||
148 | } | ||
149 | 88 | ||
150 | const struct inode_operations ocfs2_symlink_inode_operations = { | 89 | const struct inode_operations ocfs2_symlink_inode_operations = { |
151 | .readlink = page_readlink, | 90 | .readlink = generic_readlink, |
152 | .follow_link = page_follow_link_light, | 91 | .follow_link = page_follow_link_light, |
153 | .put_link = page_put_link, | 92 | .put_link = page_put_link, |
154 | .getattr = ocfs2_getattr, | 93 | .getattr = ocfs2_getattr, |
@@ -159,15 +98,3 @@ const struct inode_operations ocfs2_symlink_inode_operations = { | |||
159 | .removexattr = generic_removexattr, | 98 | .removexattr = generic_removexattr, |
160 | .fiemap = ocfs2_fiemap, | 99 | .fiemap = ocfs2_fiemap, |
161 | }; | 100 | }; |
162 | const struct inode_operations ocfs2_fast_symlink_inode_operations = { | ||
163 | .readlink = ocfs2_readlink, | ||
164 | .follow_link = ocfs2_fast_follow_link, | ||
165 | .put_link = ocfs2_fast_put_link, | ||
166 | .getattr = ocfs2_getattr, | ||
167 | .setattr = ocfs2_setattr, | ||
168 | .setxattr = generic_setxattr, | ||
169 | .getxattr = generic_getxattr, | ||
170 | .listxattr = ocfs2_listxattr, | ||
171 | .removexattr = generic_removexattr, | ||
172 | .fiemap = ocfs2_fiemap, | ||
173 | }; | ||
diff --git a/fs/ocfs2/symlink.h b/fs/ocfs2/symlink.h index 65a6c9c6ad51..71ee4245e919 100644 --- a/fs/ocfs2/symlink.h +++ b/fs/ocfs2/symlink.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #define OCFS2_SYMLINK_H | 27 | #define OCFS2_SYMLINK_H |
28 | 28 | ||
29 | extern const struct inode_operations ocfs2_symlink_inode_operations; | 29 | extern const struct inode_operations ocfs2_symlink_inode_operations; |
30 | extern const struct inode_operations ocfs2_fast_symlink_inode_operations; | 30 | extern const struct address_space_operations ocfs2_fast_symlink_aops; |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Test whether an inode is a fast symlink. | 33 | * Test whether an inode is a fast symlink. |
@@ -654,10 +654,23 @@ static inline int __get_file_write_access(struct inode *inode, | |||
654 | return error; | 654 | return error; |
655 | } | 655 | } |
656 | 656 | ||
657 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 657 | int open_check_o_direct(struct file *f) |
658 | struct file *f, | 658 | { |
659 | int (*open)(struct inode *, struct file *), | 659 | /* NB: we're sure to have correct a_ops only after f_op->open */ |
660 | const struct cred *cred) | 660 | if (f->f_flags & O_DIRECT) { |
661 | if (!f->f_mapping->a_ops || | ||
662 | ((!f->f_mapping->a_ops->direct_IO) && | ||
663 | (!f->f_mapping->a_ops->get_xip_mem))) { | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | } | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static struct file *do_dentry_open(struct dentry *dentry, struct vfsmount *mnt, | ||
671 | struct file *f, | ||
672 | int (*open)(struct inode *, struct file *), | ||
673 | const struct cred *cred) | ||
661 | { | 674 | { |
662 | static const struct file_operations empty_fops = {}; | 675 | static const struct file_operations empty_fops = {}; |
663 | struct inode *inode; | 676 | struct inode *inode; |
@@ -713,16 +726,6 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
713 | 726 | ||
714 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); | 727 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); |
715 | 728 | ||
716 | /* NB: we're sure to have correct a_ops only after f_op->open */ | ||
717 | if (f->f_flags & O_DIRECT) { | ||
718 | if (!f->f_mapping->a_ops || | ||
719 | ((!f->f_mapping->a_ops->direct_IO) && | ||
720 | (!f->f_mapping->a_ops->get_xip_mem))) { | ||
721 | fput(f); | ||
722 | f = ERR_PTR(-EINVAL); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | return f; | 729 | return f; |
727 | 730 | ||
728 | cleanup_all: | 731 | cleanup_all: |
@@ -744,12 +747,29 @@ cleanup_all: | |||
744 | f->f_path.dentry = NULL; | 747 | f->f_path.dentry = NULL; |
745 | f->f_path.mnt = NULL; | 748 | f->f_path.mnt = NULL; |
746 | cleanup_file: | 749 | cleanup_file: |
747 | put_filp(f); | ||
748 | dput(dentry); | 750 | dput(dentry); |
749 | mntput(mnt); | 751 | mntput(mnt); |
750 | return ERR_PTR(error); | 752 | return ERR_PTR(error); |
751 | } | 753 | } |
752 | 754 | ||
755 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | ||
756 | struct file *f, | ||
757 | int (*open)(struct inode *, struct file *), | ||
758 | const struct cred *cred) | ||
759 | { | ||
760 | struct file *res = do_dentry_open(dentry, mnt, f, open, cred); | ||
761 | if (!IS_ERR(res)) { | ||
762 | int error = open_check_o_direct(f); | ||
763 | if (error) { | ||
764 | fput(res); | ||
765 | res = ERR_PTR(error); | ||
766 | } | ||
767 | } else { | ||
768 | put_filp(f); | ||
769 | } | ||
770 | return res; | ||
771 | } | ||
772 | |||
753 | /** | 773 | /** |
754 | * lookup_instantiate_filp - instantiates the open intent filp | 774 | * lookup_instantiate_filp - instantiates the open intent filp |
755 | * @nd: pointer to nameidata | 775 | * @nd: pointer to nameidata |
@@ -804,13 +824,31 @@ struct file *nameidata_to_filp(struct nameidata *nd) | |||
804 | 824 | ||
805 | /* Pick up the filp from the open intent */ | 825 | /* Pick up the filp from the open intent */ |
806 | filp = nd->intent.open.file; | 826 | filp = nd->intent.open.file; |
807 | nd->intent.open.file = NULL; | ||
808 | 827 | ||
809 | /* Has the filesystem initialised the file for us? */ | 828 | /* Has the filesystem initialised the file for us? */ |
810 | if (filp->f_path.dentry == NULL) { | 829 | if (filp->f_path.dentry != NULL) { |
830 | nd->intent.open.file = NULL; | ||
831 | } else { | ||
832 | struct file *res; | ||
833 | |||
811 | path_get(&nd->path); | 834 | path_get(&nd->path); |
812 | filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, | 835 | res = do_dentry_open(nd->path.dentry, nd->path.mnt, |
813 | NULL, cred); | 836 | filp, NULL, cred); |
837 | if (!IS_ERR(res)) { | ||
838 | int error; | ||
839 | |||
840 | nd->intent.open.file = NULL; | ||
841 | BUG_ON(res != filp); | ||
842 | |||
843 | error = open_check_o_direct(filp); | ||
844 | if (error) { | ||
845 | fput(filp); | ||
846 | filp = ERR_PTR(error); | ||
847 | } | ||
848 | } else { | ||
849 | /* Allow nd->intent.open.file to be recycled */ | ||
850 | filp = res; | ||
851 | } | ||
814 | } | 852 | } |
815 | return filp; | 853 | return filp; |
816 | } | 854 | } |
@@ -654,8 +654,11 @@ out: | |||
654 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); | 654 | wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM); |
655 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 655 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
656 | } | 656 | } |
657 | if (ret > 0) | 657 | if (ret > 0) { |
658 | file_update_time(filp); | 658 | int err = file_update_time(filp); |
659 | if (err) | ||
660 | ret = err; | ||
661 | } | ||
659 | return ret; | 662 | return ret; |
660 | } | 663 | } |
661 | 664 | ||
diff --git a/fs/pnode.c b/fs/pnode.c index ab5fa9e1a79a..bed378db0758 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -257,12 +257,12 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, | |||
257 | prev_src_mnt = child; | 257 | prev_src_mnt = child; |
258 | } | 258 | } |
259 | out: | 259 | out: |
260 | br_write_lock(vfsmount_lock); | 260 | br_write_lock(&vfsmount_lock); |
261 | while (!list_empty(&tmp_list)) { | 261 | while (!list_empty(&tmp_list)) { |
262 | child = list_first_entry(&tmp_list, struct mount, mnt_hash); | 262 | child = list_first_entry(&tmp_list, struct mount, mnt_hash); |
263 | umount_tree(child, 0, &umount_list); | 263 | umount_tree(child, 0, &umount_list); |
264 | } | 264 | } |
265 | br_write_unlock(vfsmount_lock); | 265 | br_write_unlock(&vfsmount_lock); |
266 | release_mounts(&umount_list); | 266 | release_mounts(&umount_list); |
267 | return ret; | 267 | return ret; |
268 | } | 268 | } |
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index 12412852d88a..5e289a7cbad1 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c | |||
@@ -23,12 +23,12 @@ static unsigned mounts_poll(struct file *file, poll_table *wait) | |||
23 | 23 | ||
24 | poll_wait(file, &p->ns->poll, wait); | 24 | poll_wait(file, &p->ns->poll, wait); |
25 | 25 | ||
26 | br_read_lock(vfsmount_lock); | 26 | br_read_lock(&vfsmount_lock); |
27 | if (p->m.poll_event != ns->event) { | 27 | if (p->m.poll_event != ns->event) { |
28 | p->m.poll_event = ns->event; | 28 | p->m.poll_event = ns->event; |
29 | res |= POLLERR | POLLPRI; | 29 | res |= POLLERR | POLLPRI; |
30 | } | 30 | } |
31 | br_read_unlock(vfsmount_lock); | 31 | br_read_unlock(&vfsmount_lock); |
32 | 32 | ||
33 | return res; | 33 | return res; |
34 | } | 34 | } |
diff --git a/fs/readdir.c b/fs/readdir.c index cc0a8227cddf..39e3370d79cf 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -108,11 +108,11 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, | |||
108 | int error; | 108 | int error; |
109 | struct file * file; | 109 | struct file * file; |
110 | struct readdir_callback buf; | 110 | struct readdir_callback buf; |
111 | int fput_needed; | ||
111 | 112 | ||
112 | error = -EBADF; | 113 | file = fget_light(fd, &fput_needed); |
113 | file = fget(fd); | ||
114 | if (!file) | 114 | if (!file) |
115 | goto out; | 115 | return -EBADF; |
116 | 116 | ||
117 | buf.result = 0; | 117 | buf.result = 0; |
118 | buf.dirent = dirent; | 118 | buf.dirent = dirent; |
@@ -121,8 +121,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd, | |||
121 | if (buf.result) | 121 | if (buf.result) |
122 | error = buf.result; | 122 | error = buf.result; |
123 | 123 | ||
124 | fput(file); | 124 | fput_light(file, fput_needed); |
125 | out: | ||
126 | return error; | 125 | return error; |
127 | } | 126 | } |
128 | 127 | ||
@@ -195,16 +194,15 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, | |||
195 | struct file * file; | 194 | struct file * file; |
196 | struct linux_dirent __user * lastdirent; | 195 | struct linux_dirent __user * lastdirent; |
197 | struct getdents_callback buf; | 196 | struct getdents_callback buf; |
197 | int fput_needed; | ||
198 | int error; | 198 | int error; |
199 | 199 | ||
200 | error = -EFAULT; | ||
201 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 200 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
202 | goto out; | 201 | return -EFAULT; |
203 | 202 | ||
204 | error = -EBADF; | 203 | file = fget_light(fd, &fput_needed); |
205 | file = fget(fd); | ||
206 | if (!file) | 204 | if (!file) |
207 | goto out; | 205 | return -EBADF; |
208 | 206 | ||
209 | buf.current_dir = dirent; | 207 | buf.current_dir = dirent; |
210 | buf.previous = NULL; | 208 | buf.previous = NULL; |
@@ -221,8 +219,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd, | |||
221 | else | 219 | else |
222 | error = count - buf.count; | 220 | error = count - buf.count; |
223 | } | 221 | } |
224 | fput(file); | 222 | fput_light(file, fput_needed); |
225 | out: | ||
226 | return error; | 223 | return error; |
227 | } | 224 | } |
228 | 225 | ||
@@ -278,16 +275,15 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, | |||
278 | struct file * file; | 275 | struct file * file; |
279 | struct linux_dirent64 __user * lastdirent; | 276 | struct linux_dirent64 __user * lastdirent; |
280 | struct getdents_callback64 buf; | 277 | struct getdents_callback64 buf; |
278 | int fput_needed; | ||
281 | int error; | 279 | int error; |
282 | 280 | ||
283 | error = -EFAULT; | ||
284 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 281 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
285 | goto out; | 282 | return -EFAULT; |
286 | 283 | ||
287 | error = -EBADF; | 284 | file = fget_light(fd, &fput_needed); |
288 | file = fget(fd); | ||
289 | if (!file) | 285 | if (!file) |
290 | goto out; | 286 | return -EBADF; |
291 | 287 | ||
292 | buf.current_dir = dirent; | 288 | buf.current_dir = dirent; |
293 | buf.previous = NULL; | 289 | buf.previous = NULL; |
@@ -305,7 +301,6 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd, | |||
305 | else | 301 | else |
306 | error = count - buf.count; | 302 | error = count - buf.count; |
307 | } | 303 | } |
308 | fput(file); | 304 | fput_light(file, fput_needed); |
309 | out: | ||
310 | return error; | 305 | return error; |
311 | } | 306 | } |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 59d06871a850..a6d4268fb6c1 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1592,13 +1592,12 @@ struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
1592 | (fh_type == 6) ? fid->raw[5] : 0); | 1592 | (fh_type == 6) ? fid->raw[5] : 0); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | 1595 | int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, |
1596 | int need_parent) | 1596 | struct inode *parent) |
1597 | { | 1597 | { |
1598 | struct inode *inode = dentry->d_inode; | ||
1599 | int maxlen = *lenp; | 1598 | int maxlen = *lenp; |
1600 | 1599 | ||
1601 | if (need_parent && (maxlen < 5)) { | 1600 | if (parent && (maxlen < 5)) { |
1602 | *lenp = 5; | 1601 | *lenp = 5; |
1603 | return 255; | 1602 | return 255; |
1604 | } else if (maxlen < 3) { | 1603 | } else if (maxlen < 3) { |
@@ -1610,20 +1609,15 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | |||
1610 | data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); | 1609 | data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); |
1611 | data[2] = inode->i_generation; | 1610 | data[2] = inode->i_generation; |
1612 | *lenp = 3; | 1611 | *lenp = 3; |
1613 | /* no room for directory info? return what we've stored so far */ | 1612 | if (parent) { |
1614 | if (maxlen < 5 || !need_parent) | 1613 | data[3] = parent->i_ino; |
1615 | return 3; | 1614 | data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id); |
1616 | 1615 | *lenp = 5; | |
1617 | spin_lock(&dentry->d_lock); | 1616 | if (maxlen >= 6) { |
1618 | inode = dentry->d_parent->d_inode; | 1617 | data[5] = parent->i_generation; |
1619 | data[3] = inode->i_ino; | 1618 | *lenp = 6; |
1620 | data[4] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); | 1619 | } |
1621 | *lenp = 5; | 1620 | } |
1622 | if (maxlen >= 6) { | ||
1623 | data[5] = inode->i_generation; | ||
1624 | *lenp = 6; | ||
1625 | } | ||
1626 | spin_unlock(&dentry->d_lock); | ||
1627 | return *lenp; | 1621 | return *lenp; |
1628 | } | 1622 | } |
1629 | 1623 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index b1a08573fe14..afcadcc03e8a 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -1923,6 +1923,8 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1923 | * the workqueue job (flush_async_commit) needs this lock | 1923 | * the workqueue job (flush_async_commit) needs this lock |
1924 | */ | 1924 | */ |
1925 | reiserfs_write_unlock(sb); | 1925 | reiserfs_write_unlock(sb); |
1926 | |||
1927 | cancel_delayed_work_sync(&REISERFS_SB(sb)->old_work); | ||
1926 | flush_workqueue(commit_wq); | 1928 | flush_workqueue(commit_wq); |
1927 | 1929 | ||
1928 | if (!reiserfs_mounted_fs_count) { | 1930 | if (!reiserfs_mounted_fs_count) { |
@@ -3231,8 +3233,6 @@ int journal_mark_dirty(struct reiserfs_transaction_handle *th, | |||
3231 | th->t_trans_id, journal->j_trans_id); | 3233 | th->t_trans_id, journal->j_trans_id); |
3232 | } | 3234 | } |
3233 | 3235 | ||
3234 | sb->s_dirt = 1; | ||
3235 | |||
3236 | prepared = test_clear_buffer_journal_prepared(bh); | 3236 | prepared = test_clear_buffer_journal_prepared(bh); |
3237 | clear_buffer_journal_restore_dirty(bh); | 3237 | clear_buffer_journal_restore_dirty(bh); |
3238 | /* already in this transaction, we are done */ | 3238 | /* already in this transaction, we are done */ |
@@ -3316,6 +3316,7 @@ int journal_mark_dirty(struct reiserfs_transaction_handle *th, | |||
3316 | journal->j_first = cn; | 3316 | journal->j_first = cn; |
3317 | journal->j_last = cn; | 3317 | journal->j_last = cn; |
3318 | } | 3318 | } |
3319 | reiserfs_schedule_old_flush(sb); | ||
3319 | return 0; | 3320 | return 0; |
3320 | } | 3321 | } |
3321 | 3322 | ||
@@ -3492,7 +3493,7 @@ static void flush_async_commits(struct work_struct *work) | |||
3492 | ** flushes any old transactions to disk | 3493 | ** flushes any old transactions to disk |
3493 | ** ends the current transaction if it is too old | 3494 | ** ends the current transaction if it is too old |
3494 | */ | 3495 | */ |
3495 | int reiserfs_flush_old_commits(struct super_block *sb) | 3496 | void reiserfs_flush_old_commits(struct super_block *sb) |
3496 | { | 3497 | { |
3497 | time_t now; | 3498 | time_t now; |
3498 | struct reiserfs_transaction_handle th; | 3499 | struct reiserfs_transaction_handle th; |
@@ -3502,9 +3503,8 @@ int reiserfs_flush_old_commits(struct super_block *sb) | |||
3502 | /* safety check so we don't flush while we are replaying the log during | 3503 | /* safety check so we don't flush while we are replaying the log during |
3503 | * mount | 3504 | * mount |
3504 | */ | 3505 | */ |
3505 | if (list_empty(&journal->j_journal_list)) { | 3506 | if (list_empty(&journal->j_journal_list)) |
3506 | return 0; | 3507 | return; |
3507 | } | ||
3508 | 3508 | ||
3509 | /* check the current transaction. If there are no writers, and it is | 3509 | /* check the current transaction. If there are no writers, and it is |
3510 | * too old, finish it, and force the commit blocks to disk | 3510 | * too old, finish it, and force the commit blocks to disk |
@@ -3526,7 +3526,6 @@ int reiserfs_flush_old_commits(struct super_block *sb) | |||
3526 | do_journal_end(&th, sb, 1, COMMIT_NOW | WAIT); | 3526 | do_journal_end(&th, sb, 1, COMMIT_NOW | WAIT); |
3527 | } | 3527 | } |
3528 | } | 3528 | } |
3529 | return sb->s_dirt; | ||
3530 | } | 3529 | } |
3531 | 3530 | ||
3532 | /* | 3531 | /* |
@@ -3955,7 +3954,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
3955 | ** it tells us if we should continue with the journal_end, or just return | 3954 | ** it tells us if we should continue with the journal_end, or just return |
3956 | */ | 3955 | */ |
3957 | if (!check_journal_end(th, sb, nblocks, flags)) { | 3956 | if (!check_journal_end(th, sb, nblocks, flags)) { |
3958 | sb->s_dirt = 1; | 3957 | reiserfs_schedule_old_flush(sb); |
3959 | wake_queued_writers(sb); | 3958 | wake_queued_writers(sb); |
3960 | reiserfs_async_progress_wait(sb); | 3959 | reiserfs_async_progress_wait(sb); |
3961 | goto out; | 3960 | goto out; |
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index a59d27126338..33215f57ea06 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -480,6 +480,11 @@ struct reiserfs_sb_info { | |||
480 | struct dentry *priv_root; /* root of /.reiserfs_priv */ | 480 | struct dentry *priv_root; /* root of /.reiserfs_priv */ |
481 | struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */ | 481 | struct dentry *xattr_root; /* root of /.reiserfs_priv/xattrs */ |
482 | int j_errno; | 482 | int j_errno; |
483 | |||
484 | int work_queued; /* non-zero delayed work is queued */ | ||
485 | struct delayed_work old_work; /* old transactions flush delayed work */ | ||
486 | spinlock_t old_work_lock; /* protects old_work and work_queued */ | ||
487 | |||
483 | #ifdef CONFIG_QUOTA | 488 | #ifdef CONFIG_QUOTA |
484 | char *s_qf_names[MAXQUOTAS]; | 489 | char *s_qf_names[MAXQUOTAS]; |
485 | int s_jquota_fmt; | 490 | int s_jquota_fmt; |
@@ -2452,7 +2457,7 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct | |||
2452 | int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *); | 2457 | int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *); |
2453 | int reiserfs_commit_page(struct inode *inode, struct page *page, | 2458 | int reiserfs_commit_page(struct inode *inode, struct page *page, |
2454 | unsigned from, unsigned to); | 2459 | unsigned from, unsigned to); |
2455 | int reiserfs_flush_old_commits(struct super_block *); | 2460 | void reiserfs_flush_old_commits(struct super_block *); |
2456 | int reiserfs_commit_for_inode(struct inode *); | 2461 | int reiserfs_commit_for_inode(struct inode *); |
2457 | int reiserfs_inode_needs_commit(struct inode *); | 2462 | int reiserfs_inode_needs_commit(struct inode *); |
2458 | void reiserfs_update_inode_transaction(struct inode *); | 2463 | void reiserfs_update_inode_transaction(struct inode *); |
@@ -2487,6 +2492,7 @@ void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...); | |||
2487 | int reiserfs_allocate_list_bitmaps(struct super_block *s, | 2492 | int reiserfs_allocate_list_bitmaps(struct super_block *s, |
2488 | struct reiserfs_list_bitmap *, unsigned int); | 2493 | struct reiserfs_list_bitmap *, unsigned int); |
2489 | 2494 | ||
2495 | void reiserfs_schedule_old_flush(struct super_block *s); | ||
2490 | void add_save_link(struct reiserfs_transaction_handle *th, | 2496 | void add_save_link(struct reiserfs_transaction_handle *th, |
2491 | struct inode *inode, int truncate); | 2497 | struct inode *inode, int truncate); |
2492 | int remove_save_link(struct inode *inode, int truncate); | 2498 | int remove_save_link(struct inode *inode, int truncate); |
@@ -2611,8 +2617,8 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, | |||
2611 | int fh_len, int fh_type); | 2617 | int fh_len, int fh_type); |
2612 | struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, | 2618 | struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, |
2613 | int fh_len, int fh_type); | 2619 | int fh_len, int fh_type); |
2614 | int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | 2620 | int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, |
2615 | int connectable); | 2621 | struct inode *parent); |
2616 | 2622 | ||
2617 | int reiserfs_truncate_file(struct inode *, int update_timestamps); | 2623 | int reiserfs_truncate_file(struct inode *, int update_timestamps); |
2618 | void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset, | 2624 | void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset, |
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 9a17f63c3fd7..3ce02cff5e90 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -200,7 +200,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
200 | (bmap_nr_new - bmap_nr))); | 200 | (bmap_nr_new - bmap_nr))); |
201 | PUT_SB_BLOCK_COUNT(s, block_count_new); | 201 | PUT_SB_BLOCK_COUNT(s, block_count_new); |
202 | PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); | 202 | PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); |
203 | s->s_dirt = 1; | ||
204 | 203 | ||
205 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); | 204 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); |
206 | 205 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c07b7d709447..651ce767b55d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -72,20 +72,58 @@ static int reiserfs_sync_fs(struct super_block *s, int wait) | |||
72 | if (!journal_begin(&th, s, 1)) | 72 | if (!journal_begin(&th, s, 1)) |
73 | if (!journal_end_sync(&th, s, 1)) | 73 | if (!journal_end_sync(&th, s, 1)) |
74 | reiserfs_flush_old_commits(s); | 74 | reiserfs_flush_old_commits(s); |
75 | s->s_dirt = 0; /* Even if it's not true. | ||
76 | * We'll loop forever in sync_supers otherwise */ | ||
77 | reiserfs_write_unlock(s); | 75 | reiserfs_write_unlock(s); |
78 | return 0; | 76 | return 0; |
79 | } | 77 | } |
80 | 78 | ||
81 | static void reiserfs_write_super(struct super_block *s) | 79 | static void flush_old_commits(struct work_struct *work) |
82 | { | 80 | { |
81 | struct reiserfs_sb_info *sbi; | ||
82 | struct super_block *s; | ||
83 | |||
84 | sbi = container_of(work, struct reiserfs_sb_info, old_work.work); | ||
85 | s = sbi->s_journal->j_work_sb; | ||
86 | |||
87 | spin_lock(&sbi->old_work_lock); | ||
88 | sbi->work_queued = 0; | ||
89 | spin_unlock(&sbi->old_work_lock); | ||
90 | |||
83 | reiserfs_sync_fs(s, 1); | 91 | reiserfs_sync_fs(s, 1); |
84 | } | 92 | } |
85 | 93 | ||
94 | void reiserfs_schedule_old_flush(struct super_block *s) | ||
95 | { | ||
96 | struct reiserfs_sb_info *sbi = REISERFS_SB(s); | ||
97 | unsigned long delay; | ||
98 | |||
99 | if (s->s_flags & MS_RDONLY) | ||
100 | return; | ||
101 | |||
102 | spin_lock(&sbi->old_work_lock); | ||
103 | if (!sbi->work_queued) { | ||
104 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
105 | queue_delayed_work(system_long_wq, &sbi->old_work, delay); | ||
106 | sbi->work_queued = 1; | ||
107 | } | ||
108 | spin_unlock(&sbi->old_work_lock); | ||
109 | } | ||
110 | |||
111 | static void cancel_old_flush(struct super_block *s) | ||
112 | { | ||
113 | struct reiserfs_sb_info *sbi = REISERFS_SB(s); | ||
114 | |||
115 | cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); | ||
116 | spin_lock(&sbi->old_work_lock); | ||
117 | sbi->work_queued = 0; | ||
118 | spin_unlock(&sbi->old_work_lock); | ||
119 | } | ||
120 | |||
86 | static int reiserfs_freeze(struct super_block *s) | 121 | static int reiserfs_freeze(struct super_block *s) |
87 | { | 122 | { |
88 | struct reiserfs_transaction_handle th; | 123 | struct reiserfs_transaction_handle th; |
124 | |||
125 | cancel_old_flush(s); | ||
126 | |||
89 | reiserfs_write_lock(s); | 127 | reiserfs_write_lock(s); |
90 | if (!(s->s_flags & MS_RDONLY)) { | 128 | if (!(s->s_flags & MS_RDONLY)) { |
91 | int err = journal_begin(&th, s, 1); | 129 | int err = journal_begin(&th, s, 1); |
@@ -99,7 +137,6 @@ static int reiserfs_freeze(struct super_block *s) | |||
99 | journal_end_sync(&th, s, 1); | 137 | journal_end_sync(&th, s, 1); |
100 | } | 138 | } |
101 | } | 139 | } |
102 | s->s_dirt = 0; | ||
103 | reiserfs_write_unlock(s); | 140 | reiserfs_write_unlock(s); |
104 | return 0; | 141 | return 0; |
105 | } | 142 | } |
@@ -483,9 +520,6 @@ static void reiserfs_put_super(struct super_block *s) | |||
483 | 520 | ||
484 | reiserfs_write_lock(s); | 521 | reiserfs_write_lock(s); |
485 | 522 | ||
486 | if (s->s_dirt) | ||
487 | reiserfs_write_super(s); | ||
488 | |||
489 | /* change file system state to current state if it was mounted with read-write permissions */ | 523 | /* change file system state to current state if it was mounted with read-write permissions */ |
490 | if (!(s->s_flags & MS_RDONLY)) { | 524 | if (!(s->s_flags & MS_RDONLY)) { |
491 | if (!journal_begin(&th, s, 10)) { | 525 | if (!journal_begin(&th, s, 10)) { |
@@ -692,7 +726,6 @@ static const struct super_operations reiserfs_sops = { | |||
692 | .dirty_inode = reiserfs_dirty_inode, | 726 | .dirty_inode = reiserfs_dirty_inode, |
693 | .evict_inode = reiserfs_evict_inode, | 727 | .evict_inode = reiserfs_evict_inode, |
694 | .put_super = reiserfs_put_super, | 728 | .put_super = reiserfs_put_super, |
695 | .write_super = reiserfs_write_super, | ||
696 | .sync_fs = reiserfs_sync_fs, | 729 | .sync_fs = reiserfs_sync_fs, |
697 | .freeze_fs = reiserfs_freeze, | 730 | .freeze_fs = reiserfs_freeze, |
698 | .unfreeze_fs = reiserfs_unfreeze, | 731 | .unfreeze_fs = reiserfs_unfreeze, |
@@ -1400,7 +1433,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1400 | err = journal_end(&th, s, 10); | 1433 | err = journal_end(&th, s, 10); |
1401 | if (err) | 1434 | if (err) |
1402 | goto out_err; | 1435 | goto out_err; |
1403 | s->s_dirt = 0; | ||
1404 | 1436 | ||
1405 | if (!(*mount_flags & MS_RDONLY)) { | 1437 | if (!(*mount_flags & MS_RDONLY)) { |
1406 | dquot_resume(s, -1); | 1438 | dquot_resume(s, -1); |
@@ -1730,19 +1762,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1730 | return -ENOMEM; | 1762 | return -ENOMEM; |
1731 | s->s_fs_info = sbi; | 1763 | s->s_fs_info = sbi; |
1732 | /* Set default values for options: non-aggressive tails, RO on errors */ | 1764 | /* Set default values for options: non-aggressive tails, RO on errors */ |
1733 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); | 1765 | sbi->s_mount_opt |= (1 << REISERFS_SMALLTAIL); |
1734 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); | 1766 | sbi->s_mount_opt |= (1 << REISERFS_ERROR_RO); |
1735 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH); | 1767 | sbi->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH); |
1736 | /* no preallocation minimum, be smart in | 1768 | /* no preallocation minimum, be smart in |
1737 | reiserfs_file_write instead */ | 1769 | reiserfs_file_write instead */ |
1738 | REISERFS_SB(s)->s_alloc_options.preallocmin = 0; | 1770 | sbi->s_alloc_options.preallocmin = 0; |
1739 | /* Preallocate by 16 blocks (17-1) at once */ | 1771 | /* Preallocate by 16 blocks (17-1) at once */ |
1740 | REISERFS_SB(s)->s_alloc_options.preallocsize = 17; | 1772 | sbi->s_alloc_options.preallocsize = 17; |
1741 | /* setup default block allocator options */ | 1773 | /* setup default block allocator options */ |
1742 | reiserfs_init_alloc_options(s); | 1774 | reiserfs_init_alloc_options(s); |
1743 | 1775 | ||
1744 | mutex_init(&REISERFS_SB(s)->lock); | 1776 | spin_lock_init(&sbi->old_work_lock); |
1745 | REISERFS_SB(s)->lock_depth = -1; | 1777 | INIT_DELAYED_WORK(&sbi->old_work, flush_old_commits); |
1778 | mutex_init(&sbi->lock); | ||
1779 | sbi->lock_depth = -1; | ||
1746 | 1780 | ||
1747 | jdev_name = NULL; | 1781 | jdev_name = NULL; |
1748 | if (reiserfs_parse_options | 1782 | if (reiserfs_parse_options |
@@ -1751,8 +1785,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1751 | goto error_unlocked; | 1785 | goto error_unlocked; |
1752 | } | 1786 | } |
1753 | if (jdev_name && jdev_name[0]) { | 1787 | if (jdev_name && jdev_name[0]) { |
1754 | REISERFS_SB(s)->s_jdev = kstrdup(jdev_name, GFP_KERNEL); | 1788 | sbi->s_jdev = kstrdup(jdev_name, GFP_KERNEL); |
1755 | if (!REISERFS_SB(s)->s_jdev) { | 1789 | if (!sbi->s_jdev) { |
1756 | SWARN(silent, s, "", "Cannot allocate memory for " | 1790 | SWARN(silent, s, "", "Cannot allocate memory for " |
1757 | "journal device name"); | 1791 | "journal device name"); |
1758 | goto error; | 1792 | goto error; |
@@ -1810,7 +1844,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1810 | /* make data=ordered the default */ | 1844 | /* make data=ordered the default */ |
1811 | if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) && | 1845 | if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) && |
1812 | !reiserfs_data_writeback(s)) { | 1846 | !reiserfs_data_writeback(s)) { |
1813 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED); | 1847 | sbi->s_mount_opt |= (1 << REISERFS_DATA_ORDERED); |
1814 | } | 1848 | } |
1815 | 1849 | ||
1816 | if (reiserfs_data_log(s)) { | 1850 | if (reiserfs_data_log(s)) { |
@@ -2003,6 +2037,8 @@ error_unlocked: | |||
2003 | reiserfs_write_unlock(s); | 2037 | reiserfs_write_unlock(s); |
2004 | } | 2038 | } |
2005 | 2039 | ||
2040 | cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); | ||
2041 | |||
2006 | reiserfs_free_bitmap_cache(s); | 2042 | reiserfs_free_bitmap_cache(s); |
2007 | if (SB_BUFFER_WITH_SB(s)) | 2043 | if (SB_BUFFER_WITH_SB(s)) |
2008 | brelse(SB_BUFFER_WITH_SB(s)); | 2044 | brelse(SB_BUFFER_WITH_SB(s)); |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 7ae2a574cb25..9f35a37173de 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -269,12 +269,13 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, | |||
269 | if (ufd < 0) | 269 | if (ufd < 0) |
270 | kfree(ctx); | 270 | kfree(ctx); |
271 | } else { | 271 | } else { |
272 | struct file *file = fget(ufd); | 272 | int fput_needed; |
273 | struct file *file = fget_light(ufd, &fput_needed); | ||
273 | if (!file) | 274 | if (!file) |
274 | return -EBADF; | 275 | return -EBADF; |
275 | ctx = file->private_data; | 276 | ctx = file->private_data; |
276 | if (file->f_op != &signalfd_fops) { | 277 | if (file->f_op != &signalfd_fops) { |
277 | fput(file); | 278 | fput_light(file, fput_needed); |
278 | return -EINVAL; | 279 | return -EINVAL; |
279 | } | 280 | } |
280 | spin_lock_irq(¤t->sighand->siglock); | 281 | spin_lock_irq(¤t->sighand->siglock); |
@@ -282,7 +283,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, | |||
282 | spin_unlock_irq(¤t->sighand->siglock); | 283 | spin_unlock_irq(¤t->sighand->siglock); |
283 | 284 | ||
284 | wake_up(¤t->sighand->signalfd_wqh); | 285 | wake_up(¤t->sighand->signalfd_wqh); |
285 | fput(file); | 286 | fput_light(file, fput_needed); |
286 | } | 287 | } |
287 | 288 | ||
288 | return ufd; | 289 | return ufd; |
diff --git a/fs/splice.c b/fs/splice.c index 406ef2b792c2..c9f1318a3b82 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -1003,8 +1003,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
1003 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | 1003 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); |
1004 | ret = file_remove_suid(out); | 1004 | ret = file_remove_suid(out); |
1005 | if (!ret) { | 1005 | if (!ret) { |
1006 | file_update_time(out); | 1006 | ret = file_update_time(out); |
1007 | ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); | 1007 | if (!ret) |
1008 | ret = splice_from_pipe_feed(pipe, &sd, | ||
1009 | pipe_to_file); | ||
1008 | } | 1010 | } |
1009 | mutex_unlock(&inode->i_mutex); | 1011 | mutex_unlock(&inode->i_mutex); |
1010 | } while (ret > 0); | 1012 | } while (ret > 0); |
diff --git a/fs/statfs.c b/fs/statfs.c index 43e6b6fe4e85..95ad5c0e586c 100644 --- a/fs/statfs.c +++ b/fs/statfs.c | |||
@@ -87,11 +87,12 @@ int user_statfs(const char __user *pathname, struct kstatfs *st) | |||
87 | 87 | ||
88 | int fd_statfs(int fd, struct kstatfs *st) | 88 | int fd_statfs(int fd, struct kstatfs *st) |
89 | { | 89 | { |
90 | struct file *file = fget(fd); | 90 | int fput_needed; |
91 | struct file *file = fget_light(fd, &fput_needed); | ||
91 | int error = -EBADF; | 92 | int error = -EBADF; |
92 | if (file) { | 93 | if (file) { |
93 | error = vfs_statfs(&file->f_path, st); | 94 | error = vfs_statfs(&file->f_path, st); |
94 | fput(file); | 95 | fput_light(file, fput_needed); |
95 | } | 96 | } |
96 | return error; | 97 | return error; |
97 | } | 98 | } |
@@ -188,11 +188,12 @@ static int do_fsync(unsigned int fd, int datasync) | |||
188 | { | 188 | { |
189 | struct file *file; | 189 | struct file *file; |
190 | int ret = -EBADF; | 190 | int ret = -EBADF; |
191 | int fput_needed; | ||
191 | 192 | ||
192 | file = fget(fd); | 193 | file = fget_light(fd, &fput_needed); |
193 | if (file) { | 194 | if (file) { |
194 | ret = vfs_fsync(file, datasync); | 195 | ret = vfs_fsync(file, datasync); |
195 | fput(file); | 196 | fput_light(file, fput_needed); |
196 | } | 197 | } |
197 | return ret; | 198 | return ret; |
198 | } | 199 | } |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 62a2727f4ecf..a6d42efc76d2 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -1127,16 +1127,7 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1127 | struct ubifs_inode *ui = ubifs_inode(inode); | 1127 | struct ubifs_inode *ui = ubifs_inode(inode); |
1128 | 1128 | ||
1129 | mutex_lock(&ui->ui_mutex); | 1129 | mutex_lock(&ui->ui_mutex); |
1130 | stat->dev = inode->i_sb->s_dev; | 1130 | generic_fillattr(inode, stat); |
1131 | stat->ino = inode->i_ino; | ||
1132 | stat->mode = inode->i_mode; | ||
1133 | stat->nlink = inode->i_nlink; | ||
1134 | stat->uid = inode->i_uid; | ||
1135 | stat->gid = inode->i_gid; | ||
1136 | stat->rdev = inode->i_rdev; | ||
1137 | stat->atime = inode->i_atime; | ||
1138 | stat->mtime = inode->i_mtime; | ||
1139 | stat->ctime = inode->i_ctime; | ||
1140 | stat->blksize = UBIFS_BLOCK_SIZE; | 1131 | stat->blksize = UBIFS_BLOCK_SIZE; |
1141 | stat->size = ui->ui_size; | 1132 | stat->size = ui->ui_size; |
1142 | 1133 | ||
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index a165c66e3eef..18024178ac4c 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -1260,16 +1260,15 @@ static struct dentry *udf_fh_to_parent(struct super_block *sb, | |||
1260 | fid->udf.parent_partref, | 1260 | fid->udf.parent_partref, |
1261 | fid->udf.parent_generation); | 1261 | fid->udf.parent_generation); |
1262 | } | 1262 | } |
1263 | static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, | 1263 | static int udf_encode_fh(struct inode *inode, __u32 *fh, int *lenp, |
1264 | int connectable) | 1264 | struct inode *parent) |
1265 | { | 1265 | { |
1266 | int len = *lenp; | 1266 | int len = *lenp; |
1267 | struct inode *inode = de->d_inode; | ||
1268 | struct kernel_lb_addr location = UDF_I(inode)->i_location; | 1267 | struct kernel_lb_addr location = UDF_I(inode)->i_location; |
1269 | struct fid *fid = (struct fid *)fh; | 1268 | struct fid *fid = (struct fid *)fh; |
1270 | int type = FILEID_UDF_WITHOUT_PARENT; | 1269 | int type = FILEID_UDF_WITHOUT_PARENT; |
1271 | 1270 | ||
1272 | if (connectable && (len < 5)) { | 1271 | if (parent && (len < 5)) { |
1273 | *lenp = 5; | 1272 | *lenp = 5; |
1274 | return 255; | 1273 | return 255; |
1275 | } else if (len < 3) { | 1274 | } else if (len < 3) { |
@@ -1282,14 +1281,11 @@ static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, | |||
1282 | fid->udf.partref = location.partitionReferenceNum; | 1281 | fid->udf.partref = location.partitionReferenceNum; |
1283 | fid->udf.generation = inode->i_generation; | 1282 | fid->udf.generation = inode->i_generation; |
1284 | 1283 | ||
1285 | if (connectable && !S_ISDIR(inode->i_mode)) { | 1284 | if (parent) { |
1286 | spin_lock(&de->d_lock); | 1285 | location = UDF_I(parent)->i_location; |
1287 | inode = de->d_parent->d_inode; | ||
1288 | location = UDF_I(inode)->i_location; | ||
1289 | fid->udf.parent_block = location.logicalBlockNum; | 1286 | fid->udf.parent_block = location.logicalBlockNum; |
1290 | fid->udf.parent_partref = location.partitionReferenceNum; | 1287 | fid->udf.parent_partref = location.partitionReferenceNum; |
1291 | fid->udf.parent_generation = inode->i_generation; | 1288 | fid->udf.parent_generation = inode->i_generation; |
1292 | spin_unlock(&de->d_lock); | ||
1293 | *lenp = 5; | 1289 | *lenp = 5; |
1294 | type = FILEID_UDF_WITH_PARENT; | 1290 | type = FILEID_UDF_WITH_PARENT; |
1295 | } | 1291 | } |
diff --git a/fs/utimes.c b/fs/utimes.c index ba653f3dc1bc..fa4dbe451e27 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -140,18 +140,19 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times, | |||
140 | goto out; | 140 | goto out; |
141 | 141 | ||
142 | if (filename == NULL && dfd != AT_FDCWD) { | 142 | if (filename == NULL && dfd != AT_FDCWD) { |
143 | int fput_needed; | ||
143 | struct file *file; | 144 | struct file *file; |
144 | 145 | ||
145 | if (flags & AT_SYMLINK_NOFOLLOW) | 146 | if (flags & AT_SYMLINK_NOFOLLOW) |
146 | goto out; | 147 | goto out; |
147 | 148 | ||
148 | file = fget(dfd); | 149 | file = fget_light(dfd, &fput_needed); |
149 | error = -EBADF; | 150 | error = -EBADF; |
150 | if (!file) | 151 | if (!file) |
151 | goto out; | 152 | goto out; |
152 | 153 | ||
153 | error = utimes_common(&file->f_path, times); | 154 | error = utimes_common(&file->f_path, times); |
154 | fput(file); | 155 | fput_light(file, fput_needed); |
155 | } else { | 156 | } else { |
156 | struct path path; | 157 | struct path path; |
157 | int lookup_flags = 0; | 158 | int lookup_flags = 0; |
diff --git a/fs/xattr.c b/fs/xattr.c index 3c8c1cc333c7..1d7ac3790458 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -399,11 +399,12 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | |||
399 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | 399 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, |
400 | const void __user *,value, size_t, size, int, flags) | 400 | const void __user *,value, size_t, size, int, flags) |
401 | { | 401 | { |
402 | int fput_needed; | ||
402 | struct file *f; | 403 | struct file *f; |
403 | struct dentry *dentry; | 404 | struct dentry *dentry; |
404 | int error = -EBADF; | 405 | int error = -EBADF; |
405 | 406 | ||
406 | f = fget(fd); | 407 | f = fget_light(fd, &fput_needed); |
407 | if (!f) | 408 | if (!f) |
408 | return error; | 409 | return error; |
409 | dentry = f->f_path.dentry; | 410 | dentry = f->f_path.dentry; |
@@ -413,7 +414,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | |||
413 | error = setxattr(dentry, name, value, size, flags); | 414 | error = setxattr(dentry, name, value, size, flags); |
414 | mnt_drop_write_file(f); | 415 | mnt_drop_write_file(f); |
415 | } | 416 | } |
416 | fput(f); | 417 | fput_light(f, fput_needed); |
417 | return error; | 418 | return error; |
418 | } | 419 | } |
419 | 420 | ||
@@ -486,15 +487,16 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, | |||
486 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, | 487 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, |
487 | void __user *, value, size_t, size) | 488 | void __user *, value, size_t, size) |
488 | { | 489 | { |
490 | int fput_needed; | ||
489 | struct file *f; | 491 | struct file *f; |
490 | ssize_t error = -EBADF; | 492 | ssize_t error = -EBADF; |
491 | 493 | ||
492 | f = fget(fd); | 494 | f = fget_light(fd, &fput_needed); |
493 | if (!f) | 495 | if (!f) |
494 | return error; | 496 | return error; |
495 | audit_inode(NULL, f->f_path.dentry); | 497 | audit_inode(NULL, f->f_path.dentry); |
496 | error = getxattr(f->f_path.dentry, name, value, size); | 498 | error = getxattr(f->f_path.dentry, name, value, size); |
497 | fput(f); | 499 | fput_light(f, fput_needed); |
498 | return error; | 500 | return error; |
499 | } | 501 | } |
500 | 502 | ||
@@ -566,15 +568,16 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, | |||
566 | 568 | ||
567 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) | 569 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) |
568 | { | 570 | { |
571 | int fput_needed; | ||
569 | struct file *f; | 572 | struct file *f; |
570 | ssize_t error = -EBADF; | 573 | ssize_t error = -EBADF; |
571 | 574 | ||
572 | f = fget(fd); | 575 | f = fget_light(fd, &fput_needed); |
573 | if (!f) | 576 | if (!f) |
574 | return error; | 577 | return error; |
575 | audit_inode(NULL, f->f_path.dentry); | 578 | audit_inode(NULL, f->f_path.dentry); |
576 | error = listxattr(f->f_path.dentry, list, size); | 579 | error = listxattr(f->f_path.dentry, list, size); |
577 | fput(f); | 580 | fput_light(f, fput_needed); |
578 | return error; | 581 | return error; |
579 | } | 582 | } |
580 | 583 | ||
@@ -634,11 +637,12 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | |||
634 | 637 | ||
635 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | 638 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) |
636 | { | 639 | { |
640 | int fput_needed; | ||
637 | struct file *f; | 641 | struct file *f; |
638 | struct dentry *dentry; | 642 | struct dentry *dentry; |
639 | int error = -EBADF; | 643 | int error = -EBADF; |
640 | 644 | ||
641 | f = fget(fd); | 645 | f = fget_light(fd, &fput_needed); |
642 | if (!f) | 646 | if (!f) |
643 | return error; | 647 | return error; |
644 | dentry = f->f_path.dentry; | 648 | dentry = f->f_path.dentry; |
@@ -648,7 +652,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | |||
648 | error = removexattr(dentry, name); | 652 | error = removexattr(dentry, name); |
649 | mnt_drop_write_file(f); | 653 | mnt_drop_write_file(f); |
650 | } | 654 | } |
651 | fput(f); | 655 | fput_light(f, fput_needed); |
652 | return error; | 656 | return error; |
653 | } | 657 | } |
654 | 658 | ||
diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index a907de565db3..4a7286c1dc80 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c | |||
@@ -46,7 +46,7 @@ kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | void * | 48 | void * |
49 | kmem_alloc(size_t size, unsigned int __nocast flags) | 49 | kmem_alloc(size_t size, xfs_km_flags_t flags) |
50 | { | 50 | { |
51 | int retries = 0; | 51 | int retries = 0; |
52 | gfp_t lflags = kmem_flags_convert(flags); | 52 | gfp_t lflags = kmem_flags_convert(flags); |
@@ -65,7 +65,7 @@ kmem_alloc(size_t size, unsigned int __nocast flags) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | void * | 67 | void * |
68 | kmem_zalloc(size_t size, unsigned int __nocast flags) | 68 | kmem_zalloc(size_t size, xfs_km_flags_t flags) |
69 | { | 69 | { |
70 | void *ptr; | 70 | void *ptr; |
71 | 71 | ||
@@ -87,7 +87,7 @@ kmem_free(const void *ptr) | |||
87 | 87 | ||
88 | void * | 88 | void * |
89 | kmem_realloc(const void *ptr, size_t newsize, size_t oldsize, | 89 | kmem_realloc(const void *ptr, size_t newsize, size_t oldsize, |
90 | unsigned int __nocast flags) | 90 | xfs_km_flags_t flags) |
91 | { | 91 | { |
92 | void *new; | 92 | void *new; |
93 | 93 | ||
@@ -102,7 +102,7 @@ kmem_realloc(const void *ptr, size_t newsize, size_t oldsize, | |||
102 | } | 102 | } |
103 | 103 | ||
104 | void * | 104 | void * |
105 | kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags) | 105 | kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags) |
106 | { | 106 | { |
107 | int retries = 0; | 107 | int retries = 0; |
108 | gfp_t lflags = kmem_flags_convert(flags); | 108 | gfp_t lflags = kmem_flags_convert(flags); |
@@ -121,7 +121,7 @@ kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | void * | 123 | void * |
124 | kmem_zone_zalloc(kmem_zone_t *zone, unsigned int __nocast flags) | 124 | kmem_zone_zalloc(kmem_zone_t *zone, xfs_km_flags_t flags) |
125 | { | 125 | { |
126 | void *ptr; | 126 | void *ptr; |
127 | 127 | ||
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index ab7c53fe346e..b2f2620f9a87 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h | |||
@@ -27,10 +27,11 @@ | |||
27 | * General memory allocation interfaces | 27 | * General memory allocation interfaces |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define KM_SLEEP 0x0001u | 30 | typedef unsigned __bitwise xfs_km_flags_t; |
31 | #define KM_NOSLEEP 0x0002u | 31 | #define KM_SLEEP ((__force xfs_km_flags_t)0x0001u) |
32 | #define KM_NOFS 0x0004u | 32 | #define KM_NOSLEEP ((__force xfs_km_flags_t)0x0002u) |
33 | #define KM_MAYFAIL 0x0008u | 33 | #define KM_NOFS ((__force xfs_km_flags_t)0x0004u) |
34 | #define KM_MAYFAIL ((__force xfs_km_flags_t)0x0008u) | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * We use a special process flag to avoid recursive callbacks into | 37 | * We use a special process flag to avoid recursive callbacks into |
@@ -38,7 +39,7 @@ | |||
38 | * warnings, so we explicitly skip any generic ones (silly of us). | 39 | * warnings, so we explicitly skip any generic ones (silly of us). |
39 | */ | 40 | */ |
40 | static inline gfp_t | 41 | static inline gfp_t |
41 | kmem_flags_convert(unsigned int __nocast flags) | 42 | kmem_flags_convert(xfs_km_flags_t flags) |
42 | { | 43 | { |
43 | gfp_t lflags; | 44 | gfp_t lflags; |
44 | 45 | ||
@@ -54,9 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags) | |||
54 | return lflags; | 55 | return lflags; |
55 | } | 56 | } |
56 | 57 | ||
57 | extern void *kmem_alloc(size_t, unsigned int __nocast); | 58 | extern void *kmem_alloc(size_t, xfs_km_flags_t); |
58 | extern void *kmem_zalloc(size_t, unsigned int __nocast); | 59 | extern void *kmem_zalloc(size_t, xfs_km_flags_t); |
59 | extern void *kmem_realloc(const void *, size_t, size_t, unsigned int __nocast); | 60 | extern void *kmem_realloc(const void *, size_t, size_t, xfs_km_flags_t); |
60 | extern void kmem_free(const void *); | 61 | extern void kmem_free(const void *); |
61 | 62 | ||
62 | static inline void *kmem_zalloc_large(size_t size) | 63 | static inline void *kmem_zalloc_large(size_t size) |
@@ -107,7 +108,7 @@ kmem_zone_destroy(kmem_zone_t *zone) | |||
107 | kmem_cache_destroy(zone); | 108 | kmem_cache_destroy(zone); |
108 | } | 109 | } |
109 | 110 | ||
110 | extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast); | 111 | extern void *kmem_zone_alloc(kmem_zone_t *, xfs_km_flags_t); |
111 | extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast); | 112 | extern void *kmem_zone_zalloc(kmem_zone_t *, xfs_km_flags_t); |
112 | 113 | ||
113 | #endif /* __XFS_SUPPORT_KMEM_H__ */ | 114 | #endif /* __XFS_SUPPORT_KMEM_H__ */ |
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 2d25d19c4ea1..42679223a0fd 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -52,19 +52,18 @@ static int xfs_fileid_length(int fileid_type) | |||
52 | 52 | ||
53 | STATIC int | 53 | STATIC int |
54 | xfs_fs_encode_fh( | 54 | xfs_fs_encode_fh( |
55 | struct dentry *dentry, | 55 | struct inode *inode, |
56 | __u32 *fh, | 56 | __u32 *fh, |
57 | int *max_len, | 57 | int *max_len, |
58 | int connectable) | 58 | struct inode *parent) |
59 | { | 59 | { |
60 | struct fid *fid = (struct fid *)fh; | 60 | struct fid *fid = (struct fid *)fh; |
61 | struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh; | 61 | struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh; |
62 | struct inode *inode = dentry->d_inode; | ||
63 | int fileid_type; | 62 | int fileid_type; |
64 | int len; | 63 | int len; |
65 | 64 | ||
66 | /* Directories don't need their parent encoded, they have ".." */ | 65 | /* Directories don't need their parent encoded, they have ".." */ |
67 | if (S_ISDIR(inode->i_mode) || !connectable) | 66 | if (!parent) |
68 | fileid_type = FILEID_INO32_GEN; | 67 | fileid_type = FILEID_INO32_GEN; |
69 | else | 68 | else |
70 | fileid_type = FILEID_INO32_GEN_PARENT; | 69 | fileid_type = FILEID_INO32_GEN_PARENT; |
@@ -96,20 +95,16 @@ xfs_fs_encode_fh( | |||
96 | 95 | ||
97 | switch (fileid_type) { | 96 | switch (fileid_type) { |
98 | case FILEID_INO32_GEN_PARENT: | 97 | case FILEID_INO32_GEN_PARENT: |
99 | spin_lock(&dentry->d_lock); | 98 | fid->i32.parent_ino = XFS_I(parent)->i_ino; |
100 | fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; | 99 | fid->i32.parent_gen = parent->i_generation; |
101 | fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; | ||
102 | spin_unlock(&dentry->d_lock); | ||
103 | /*FALLTHRU*/ | 100 | /*FALLTHRU*/ |
104 | case FILEID_INO32_GEN: | 101 | case FILEID_INO32_GEN: |
105 | fid->i32.ino = XFS_I(inode)->i_ino; | 102 | fid->i32.ino = XFS_I(inode)->i_ino; |
106 | fid->i32.gen = inode->i_generation; | 103 | fid->i32.gen = inode->i_generation; |
107 | break; | 104 | break; |
108 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: | 105 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: |
109 | spin_lock(&dentry->d_lock); | 106 | fid64->parent_ino = XFS_I(parent)->i_ino; |
110 | fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; | 107 | fid64->parent_gen = parent->i_generation; |
111 | fid64->parent_gen = dentry->d_parent->d_inode->i_generation; | ||
112 | spin_unlock(&dentry->d_lock); | ||
113 | /*FALLTHRU*/ | 108 | /*FALLTHRU*/ |
114 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: | 109 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: |
115 | fid64->ino = XFS_I(inode)->i_ino; | 110 | fid64->ino = XFS_I(inode)->i_ino; |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 8d214b87f6bb..9f7ec15a6522 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -586,8 +586,11 @@ restart: | |||
586 | * lock above. Eventually we should look into a way to avoid | 586 | * lock above. Eventually we should look into a way to avoid |
587 | * the pointless lock roundtrip. | 587 | * the pointless lock roundtrip. |
588 | */ | 588 | */ |
589 | if (likely(!(file->f_mode & FMODE_NOCMTIME))) | 589 | if (likely(!(file->f_mode & FMODE_NOCMTIME))) { |
590 | file_update_time(file); | 590 | error = file_update_time(file); |
591 | if (error) | ||
592 | return error; | ||
593 | } | ||
591 | 594 | ||
592 | /* | 595 | /* |
593 | * If we're writing the file then make sure to clear the setuid and | 596 | * If we're writing the file then make sure to clear the setuid and |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 6b965bf450e4..f30d9807dc48 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -3152,7 +3152,7 @@ xlog_ticket_alloc( | |||
3152 | int cnt, | 3152 | int cnt, |
3153 | char client, | 3153 | char client, |
3154 | bool permanent, | 3154 | bool permanent, |
3155 | int alloc_flags) | 3155 | xfs_km_flags_t alloc_flags) |
3156 | { | 3156 | { |
3157 | struct xlog_ticket *tic; | 3157 | struct xlog_ticket *tic; |
3158 | uint num_headers; | 3158 | uint num_headers; |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 735ff1ee53da..5bc33261f5be 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -555,7 +555,7 @@ extern void xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int); | |||
555 | extern kmem_zone_t *xfs_log_ticket_zone; | 555 | extern kmem_zone_t *xfs_log_ticket_zone; |
556 | struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, | 556 | struct xlog_ticket *xlog_ticket_alloc(struct log *log, int unit_bytes, |
557 | int count, char client, bool permanent, | 557 | int count, char client, bool permanent, |
558 | int alloc_flags); | 558 | xfs_km_flags_t alloc_flags); |
559 | 559 | ||
560 | 560 | ||
561 | static inline void | 561 | static inline void |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index cdf896fcbfa4..fdf324508c5e 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -584,7 +584,7 @@ xfs_trans_t * | |||
584 | _xfs_trans_alloc( | 584 | _xfs_trans_alloc( |
585 | xfs_mount_t *mp, | 585 | xfs_mount_t *mp, |
586 | uint type, | 586 | uint type, |
587 | uint memflags) | 587 | xfs_km_flags_t memflags) |
588 | { | 588 | { |
589 | xfs_trans_t *tp; | 589 | xfs_trans_t *tp; |
590 | 590 | ||
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 7ab99e1898c8..7c37b533aa8e 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -443,7 +443,7 @@ typedef struct xfs_trans { | |||
443 | * XFS transaction mechanism exported interfaces. | 443 | * XFS transaction mechanism exported interfaces. |
444 | */ | 444 | */ |
445 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); | 445 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); |
446 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint); | 446 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t); |
447 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); | 447 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); |
448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, | 448 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, |
449 | uint, uint); | 449 | uint, uint); |