diff options
33 files changed, 488 insertions, 465 deletions
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index cb713df81180..b30dd8154cc2 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl | |||
| @@ -384,3 +384,5 @@ | |||
| 384 | 375 i386 membarrier sys_membarrier | 384 | 375 i386 membarrier sys_membarrier |
| 385 | 376 i386 mlock2 sys_mlock2 | 385 | 376 i386 mlock2 sys_mlock2 |
| 386 | 377 i386 copy_file_range sys_copy_file_range | 386 | 377 i386 copy_file_range sys_copy_file_range |
| 387 | 378 i386 preadv2 sys_preadv2 | ||
| 388 | 379 i386 pwritev2 sys_pwritev2 | ||
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index dc1040a50bdc..31cec929eb8d 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl | |||
| @@ -333,6 +333,8 @@ | |||
| 333 | 324 common membarrier sys_membarrier | 333 | 324 common membarrier sys_membarrier |
| 334 | 325 common mlock2 sys_mlock2 | 334 | 325 common mlock2 sys_mlock2 |
| 335 | 326 common copy_file_range sys_copy_file_range | 335 | 326 common copy_file_range sys_copy_file_range |
| 336 | 327 64 preadv2 sys_preadv2 | ||
| 337 | 328 64 pwritev2 sys_pwritev2 | ||
| 336 | 338 | ||
| 337 | # | 339 | # |
| 338 | # x32-specific system call numbers start at 512 to avoid cache impact | 340 | # x32-specific system call numbers start at 512 to avoid cache impact |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index c6d7d3dbd52a..75dd739ac3e6 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -537,8 +537,6 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, u | |||
| 537 | ino->dentry = dentry; | 537 | ino->dentry = dentry; |
| 538 | 538 | ||
| 539 | autofs4_add_active(dentry); | 539 | autofs4_add_active(dentry); |
| 540 | |||
| 541 | d_instantiate(dentry, NULL); | ||
| 542 | } | 540 | } |
| 543 | return NULL; | 541 | return NULL; |
| 544 | } | 542 | } |
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 452e98dd7560..1ee54ffd3a24 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c | |||
| @@ -162,6 +162,8 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, | |||
| 162 | size_t buflen, loff_t *pos) | 162 | size_t buflen, loff_t *pos) |
| 163 | { | 163 | { |
| 164 | struct cachefiles_cache *cache = file->private_data; | 164 | struct cachefiles_cache *cache = file->private_data; |
| 165 | unsigned long long b_released; | ||
| 166 | unsigned f_released; | ||
| 165 | char buffer[256]; | 167 | char buffer[256]; |
| 166 | int n; | 168 | int n; |
| 167 | 169 | ||
| @@ -174,6 +176,8 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, | |||
| 174 | cachefiles_has_space(cache, 0, 0); | 176 | cachefiles_has_space(cache, 0, 0); |
| 175 | 177 | ||
| 176 | /* summarise */ | 178 | /* summarise */ |
| 179 | f_released = atomic_xchg(&cache->f_released, 0); | ||
| 180 | b_released = atomic_long_xchg(&cache->b_released, 0); | ||
| 177 | clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags); | 181 | clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags); |
| 178 | 182 | ||
| 179 | n = snprintf(buffer, sizeof(buffer), | 183 | n = snprintf(buffer, sizeof(buffer), |
| @@ -183,15 +187,18 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, | |||
| 183 | " fstop=%llx" | 187 | " fstop=%llx" |
| 184 | " brun=%llx" | 188 | " brun=%llx" |
| 185 | " bcull=%llx" | 189 | " bcull=%llx" |
| 186 | " bstop=%llx", | 190 | " bstop=%llx" |
| 191 | " freleased=%x" | ||
| 192 | " breleased=%llx", | ||
| 187 | test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0', | 193 | test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0', |
| 188 | (unsigned long long) cache->frun, | 194 | (unsigned long long) cache->frun, |
| 189 | (unsigned long long) cache->fcull, | 195 | (unsigned long long) cache->fcull, |
| 190 | (unsigned long long) cache->fstop, | 196 | (unsigned long long) cache->fstop, |
| 191 | (unsigned long long) cache->brun, | 197 | (unsigned long long) cache->brun, |
| 192 | (unsigned long long) cache->bcull, | 198 | (unsigned long long) cache->bcull, |
| 193 | (unsigned long long) cache->bstop | 199 | (unsigned long long) cache->bstop, |
| 194 | ); | 200 | f_released, |
| 201 | b_released); | ||
| 195 | 202 | ||
| 196 | if (n > buflen) | 203 | if (n > buflen) |
| 197 | return -EMSGSIZE; | 204 | return -EMSGSIZE; |
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 675a3332d72f..861d611b8c05 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c | |||
| @@ -291,15 +291,8 @@ static void cachefiles_drop_object(struct fscache_object *_object) | |||
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | /* note that the object is now inactive */ | 293 | /* note that the object is now inactive */ |
| 294 | if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { | 294 | if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) |
| 295 | write_lock(&cache->active_lock); | 295 | cachefiles_mark_object_inactive(cache, object); |
| 296 | if (!test_and_clear_bit(CACHEFILES_OBJECT_ACTIVE, | ||
| 297 | &object->flags)) | ||
| 298 | BUG(); | ||
| 299 | rb_erase(&object->active_node, &cache->active_nodes); | ||
| 300 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); | ||
| 301 | write_unlock(&cache->active_lock); | ||
| 302 | } | ||
| 303 | 296 | ||
| 304 | dput(object->dentry); | 297 | dput(object->dentry); |
| 305 | object->dentry = NULL; | 298 | object->dentry = NULL; |
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 9c4b737a54df..2fcde1a34b7c 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h | |||
| @@ -66,6 +66,8 @@ struct cachefiles_cache { | |||
| 66 | struct rb_root active_nodes; /* active nodes (can't be culled) */ | 66 | struct rb_root active_nodes; /* active nodes (can't be culled) */ |
| 67 | rwlock_t active_lock; /* lock for active_nodes */ | 67 | rwlock_t active_lock; /* lock for active_nodes */ |
| 68 | atomic_t gravecounter; /* graveyard uniquifier */ | 68 | atomic_t gravecounter; /* graveyard uniquifier */ |
| 69 | atomic_t f_released; /* number of objects released lately */ | ||
| 70 | atomic_long_t b_released; /* number of blocks released lately */ | ||
| 69 | unsigned frun_percent; /* when to stop culling (% files) */ | 71 | unsigned frun_percent; /* when to stop culling (% files) */ |
| 70 | unsigned fcull_percent; /* when to start culling (% files) */ | 72 | unsigned fcull_percent; /* when to start culling (% files) */ |
| 71 | unsigned fstop_percent; /* when to stop allocating (% files) */ | 73 | unsigned fstop_percent; /* when to stop allocating (% files) */ |
| @@ -157,6 +159,8 @@ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type); | |||
| 157 | /* | 159 | /* |
| 158 | * namei.c | 160 | * namei.c |
| 159 | */ | 161 | */ |
| 162 | extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, | ||
| 163 | struct cachefiles_object *object); | ||
| 160 | extern int cachefiles_delete_object(struct cachefiles_cache *cache, | 164 | extern int cachefiles_delete_object(struct cachefiles_cache *cache, |
| 161 | struct cachefiles_object *object); | 165 | struct cachefiles_object *object); |
| 162 | extern int cachefiles_walk_to_object(struct cachefiles_object *parent, | 166 | extern int cachefiles_walk_to_object(struct cachefiles_object *parent, |
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 1c2334c163dd..4ae75006e73b 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
| @@ -258,6 +258,28 @@ requeue: | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /* | 260 | /* |
| 261 | * Mark an object as being inactive. | ||
| 262 | */ | ||
| 263 | void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, | ||
| 264 | struct cachefiles_object *object) | ||
| 265 | { | ||
| 266 | write_lock(&cache->active_lock); | ||
| 267 | rb_erase(&object->active_node, &cache->active_nodes); | ||
| 268 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | ||
| 269 | write_unlock(&cache->active_lock); | ||
| 270 | |||
| 271 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); | ||
| 272 | |||
| 273 | /* This object can now be culled, so we need to let the daemon know | ||
| 274 | * that there is something it can remove if it needs to. | ||
| 275 | */ | ||
| 276 | atomic_long_add(d_backing_inode(object->dentry)->i_blocks, | ||
| 277 | &cache->b_released); | ||
| 278 | if (atomic_inc_return(&cache->f_released)) | ||
| 279 | cachefiles_state_changed(cache); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* | ||
| 261 | * delete an object representation from the cache | 283 | * delete an object representation from the cache |
| 262 | * - file backed objects are unlinked | 284 | * - file backed objects are unlinked |
| 263 | * - directory backed objects are stuffed into the graveyard for userspace to | 285 | * - directory backed objects are stuffed into the graveyard for userspace to |
| @@ -684,11 +706,7 @@ mark_active_timed_out: | |||
| 684 | 706 | ||
| 685 | check_error: | 707 | check_error: |
| 686 | _debug("check error %d", ret); | 708 | _debug("check error %d", ret); |
| 687 | write_lock(&cache->active_lock); | 709 | cachefiles_mark_object_inactive(cache, object); |
| 688 | rb_erase(&object->active_node, &cache->active_nodes); | ||
| 689 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | ||
| 690 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); | ||
| 691 | write_unlock(&cache->active_lock); | ||
| 692 | release_dentry: | 710 | release_dentry: |
| 693 | dput(object->dentry); | 711 | dput(object->dentry); |
| 694 | object->dentry = NULL; | 712 | object->dentry = NULL; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index fb4ba2e4e2a5..be2d87f33177 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
| @@ -975,13 +975,8 @@ out_unlock: | |||
| 975 | /* | 975 | /* |
| 976 | * splice a dentry to an inode. | 976 | * splice a dentry to an inode. |
| 977 | * caller must hold directory i_mutex for this to be safe. | 977 | * caller must hold directory i_mutex for this to be safe. |
| 978 | * | ||
| 979 | * we will only rehash the resulting dentry if @prehash is | ||
| 980 | * true; @prehash will be set to false (for the benefit of | ||
| 981 | * the caller) if we fail. | ||
| 982 | */ | 978 | */ |
| 983 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | 979 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in) |
| 984 | bool *prehash) | ||
| 985 | { | 980 | { |
| 986 | struct dentry *realdn; | 981 | struct dentry *realdn; |
| 987 | 982 | ||
| @@ -994,8 +989,6 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
| 994 | if (IS_ERR(realdn)) { | 989 | if (IS_ERR(realdn)) { |
| 995 | pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", | 990 | pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", |
| 996 | PTR_ERR(realdn), dn, in, ceph_vinop(in)); | 991 | PTR_ERR(realdn), dn, in, ceph_vinop(in)); |
| 997 | if (prehash) | ||
| 998 | *prehash = false; /* don't rehash on error */ | ||
| 999 | dn = realdn; /* note realdn contains the error */ | 992 | dn = realdn; /* note realdn contains the error */ |
| 1000 | goto out; | 993 | goto out; |
| 1001 | } else if (realdn) { | 994 | } else if (realdn) { |
| @@ -1011,8 +1004,6 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
| 1011 | dout("dn %p attached to %p ino %llx.%llx\n", | 1004 | dout("dn %p attached to %p ino %llx.%llx\n", |
| 1012 | dn, d_inode(dn), ceph_vinop(d_inode(dn))); | 1005 | dn, d_inode(dn), ceph_vinop(d_inode(dn))); |
| 1013 | } | 1006 | } |
| 1014 | if ((!prehash || *prehash) && d_unhashed(dn)) | ||
| 1015 | d_rehash(dn); | ||
| 1016 | out: | 1007 | out: |
| 1017 | return dn; | 1008 | return dn; |
| 1018 | } | 1009 | } |
| @@ -1245,10 +1236,8 @@ retry_lookup: | |||
| 1245 | dout("d_delete %p\n", dn); | 1236 | dout("d_delete %p\n", dn); |
| 1246 | d_delete(dn); | 1237 | d_delete(dn); |
| 1247 | } else { | 1238 | } else { |
| 1248 | dout("d_instantiate %p NULL\n", dn); | ||
| 1249 | d_instantiate(dn, NULL); | ||
| 1250 | if (have_lease && d_unhashed(dn)) | 1239 | if (have_lease && d_unhashed(dn)) |
| 1251 | d_rehash(dn); | 1240 | d_add(dn, NULL); |
| 1252 | update_dentry_lease(dn, rinfo->dlease, | 1241 | update_dentry_lease(dn, rinfo->dlease, |
| 1253 | session, | 1242 | session, |
| 1254 | req->r_request_started); | 1243 | req->r_request_started); |
| @@ -1260,7 +1249,7 @@ retry_lookup: | |||
| 1260 | if (d_really_is_negative(dn)) { | 1249 | if (d_really_is_negative(dn)) { |
| 1261 | ceph_dir_clear_ordered(dir); | 1250 | ceph_dir_clear_ordered(dir); |
| 1262 | ihold(in); | 1251 | ihold(in); |
| 1263 | dn = splice_dentry(dn, in, &have_lease); | 1252 | dn = splice_dentry(dn, in); |
| 1264 | if (IS_ERR(dn)) { | 1253 | if (IS_ERR(dn)) { |
| 1265 | err = PTR_ERR(dn); | 1254 | err = PTR_ERR(dn); |
| 1266 | goto done; | 1255 | goto done; |
| @@ -1290,7 +1279,7 @@ retry_lookup: | |||
| 1290 | dout(" linking snapped dir %p to dn %p\n", in, dn); | 1279 | dout(" linking snapped dir %p to dn %p\n", in, dn); |
| 1291 | ceph_dir_clear_ordered(dir); | 1280 | ceph_dir_clear_ordered(dir); |
| 1292 | ihold(in); | 1281 | ihold(in); |
| 1293 | dn = splice_dentry(dn, in, NULL); | 1282 | dn = splice_dentry(dn, in); |
| 1294 | if (IS_ERR(dn)) { | 1283 | if (IS_ERR(dn)) { |
| 1295 | err = PTR_ERR(dn); | 1284 | err = PTR_ERR(dn); |
| 1296 | goto done; | 1285 | goto done; |
| @@ -1501,7 +1490,7 @@ retry_lookup: | |||
| 1501 | } | 1490 | } |
| 1502 | 1491 | ||
| 1503 | if (d_really_is_negative(dn)) { | 1492 | if (d_really_is_negative(dn)) { |
| 1504 | struct dentry *realdn = splice_dentry(dn, in, NULL); | 1493 | struct dentry *realdn = splice_dentry(dn, in); |
| 1505 | if (IS_ERR(realdn)) { | 1494 | if (IS_ERR(realdn)) { |
| 1506 | err = PTR_ERR(realdn); | 1495 | err = PTR_ERR(realdn); |
| 1507 | d_drop(dn); | 1496 | d_drop(dn); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index c48ca13673e3..09b1db2cac31 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -642,9 +642,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
| 642 | while (*s && *s != sep) | 642 | while (*s && *s != sep) |
| 643 | s++; | 643 | s++; |
| 644 | 644 | ||
| 645 | inode_lock(dir); | 645 | child = lookup_one_len_unlocked(p, dentry, s - p); |
| 646 | child = lookup_one_len(p, dentry, s - p); | ||
| 647 | inode_unlock(dir); | ||
| 648 | dput(dentry); | 646 | dput(dentry); |
| 649 | dentry = child; | 647 | dentry = child; |
| 650 | } while (!IS_ERR(dentry)); | 648 | } while (!IS_ERR(dentry)); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index f419519ec41f..214ec14149d9 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
| @@ -432,14 +432,9 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den | |||
| 432 | (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ? | 432 | (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ? |
| 433 | configfs_init_bin_file : | 433 | configfs_init_bin_file : |
| 434 | configfs_init_file); | 434 | configfs_init_file); |
| 435 | if (error) { | 435 | if (error) |
| 436 | configfs_put(sd); | 436 | configfs_put(sd); |
| 437 | return error; | 437 | return error; |
| 438 | } | ||
| 439 | |||
| 440 | d_rehash(dentry); | ||
| 441 | |||
| 442 | return 0; | ||
| 443 | } | 438 | } |
| 444 | 439 | ||
| 445 | static struct dentry * configfs_lookup(struct inode *dir, | 440 | static struct dentry * configfs_lookup(struct inode *dir, |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index cee087d8f7e0..45811ea3fd87 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
| @@ -199,9 +199,17 @@ int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct in | |||
| 199 | configfs_set_inode_lock_class(sd, inode); | 199 | configfs_set_inode_lock_class(sd, inode); |
| 200 | 200 | ||
| 201 | init(inode); | 201 | init(inode); |
| 202 | d_instantiate(dentry, inode); | 202 | if (S_ISDIR(mode) || S_ISLNK(mode)) { |
| 203 | if (S_ISDIR(mode) || S_ISLNK(mode)) | 203 | /* |
| 204 | * ->symlink(), ->mkdir(), configfs_register_subsystem() or | ||
| 205 | * create_default_group() - already hashed. | ||
| 206 | */ | ||
| 207 | d_instantiate(dentry, inode); | ||
| 204 | dget(dentry); /* pin link and directory dentries in core */ | 208 | dget(dentry); /* pin link and directory dentries in core */ |
| 209 | } else { | ||
| 210 | /* ->lookup() */ | ||
| 211 | d_add(dentry, inode); | ||
| 212 | } | ||
| 205 | return error; | 213 | return error; |
| 206 | } | 214 | } |
| 207 | 215 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 2398f9f94337..32ceae3e6112 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -1745,13 +1745,12 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
| 1745 | unsigned add_flags = d_flags_for_inode(inode); | 1745 | unsigned add_flags = d_flags_for_inode(inode); |
| 1746 | 1746 | ||
| 1747 | spin_lock(&dentry->d_lock); | 1747 | spin_lock(&dentry->d_lock); |
| 1748 | if (inode) | 1748 | hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); |
| 1749 | hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); | ||
| 1750 | raw_write_seqcount_begin(&dentry->d_seq); | 1749 | raw_write_seqcount_begin(&dentry->d_seq); |
| 1751 | __d_set_inode_and_type(dentry, inode, add_flags); | 1750 | __d_set_inode_and_type(dentry, inode, add_flags); |
| 1752 | raw_write_seqcount_end(&dentry->d_seq); | 1751 | raw_write_seqcount_end(&dentry->d_seq); |
| 1752 | __fsnotify_d_instantiate(dentry); | ||
| 1753 | spin_unlock(&dentry->d_lock); | 1753 | spin_unlock(&dentry->d_lock); |
| 1754 | fsnotify_d_instantiate(dentry, inode); | ||
| 1755 | } | 1754 | } |
| 1756 | 1755 | ||
| 1757 | /** | 1756 | /** |
| @@ -1772,91 +1771,16 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
| 1772 | void d_instantiate(struct dentry *entry, struct inode * inode) | 1771 | void d_instantiate(struct dentry *entry, struct inode * inode) |
| 1773 | { | 1772 | { |
| 1774 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); | 1773 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); |
| 1775 | if (inode) | 1774 | if (inode) { |
| 1776 | spin_lock(&inode->i_lock); | 1775 | spin_lock(&inode->i_lock); |
| 1777 | __d_instantiate(entry, inode); | 1776 | __d_instantiate(entry, inode); |
| 1778 | if (inode) | ||
| 1779 | spin_unlock(&inode->i_lock); | 1777 | spin_unlock(&inode->i_lock); |
| 1778 | } | ||
| 1780 | security_d_instantiate(entry, inode); | 1779 | security_d_instantiate(entry, inode); |
| 1781 | } | 1780 | } |
| 1782 | EXPORT_SYMBOL(d_instantiate); | 1781 | EXPORT_SYMBOL(d_instantiate); |
| 1783 | 1782 | ||
| 1784 | /** | 1783 | /** |
| 1785 | * d_instantiate_unique - instantiate a non-aliased dentry | ||
| 1786 | * @entry: dentry to instantiate | ||
| 1787 | * @inode: inode to attach to this dentry | ||
| 1788 | * | ||
| 1789 | * Fill in inode information in the entry. On success, it returns NULL. | ||
| 1790 | * If an unhashed alias of "entry" already exists, then we return the | ||
| 1791 | * aliased dentry instead and drop one reference to inode. | ||
| 1792 | * | ||
| 1793 | * Note that in order to avoid conflicts with rename() etc, the caller | ||
| 1794 | * had better be holding the parent directory semaphore. | ||
| 1795 | * | ||
| 1796 | * This also assumes that the inode count has been incremented | ||
| 1797 | * (or otherwise set) by the caller to indicate that it is now | ||
| 1798 | * in use by the dcache. | ||
| 1799 | */ | ||
| 1800 | static struct dentry *__d_instantiate_unique(struct dentry *entry, | ||
| 1801 | struct inode *inode) | ||
| 1802 | { | ||
| 1803 | struct dentry *alias; | ||
| 1804 | int len = entry->d_name.len; | ||
| 1805 | const char *name = entry->d_name.name; | ||
| 1806 | unsigned int hash = entry->d_name.hash; | ||
| 1807 | |||
| 1808 | if (!inode) { | ||
| 1809 | __d_instantiate(entry, NULL); | ||
| 1810 | return NULL; | ||
| 1811 | } | ||
| 1812 | |||
| 1813 | hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { | ||
| 1814 | /* | ||
| 1815 | * Don't need alias->d_lock here, because aliases with | ||
| 1816 | * d_parent == entry->d_parent are not subject to name or | ||
| 1817 | * parent changes, because the parent inode i_mutex is held. | ||
| 1818 | */ | ||
| 1819 | if (alias->d_name.hash != hash) | ||
| 1820 | continue; | ||
| 1821 | if (alias->d_parent != entry->d_parent) | ||
| 1822 | continue; | ||
| 1823 | if (alias->d_name.len != len) | ||
| 1824 | continue; | ||
| 1825 | if (dentry_cmp(alias, name, len)) | ||
| 1826 | continue; | ||
| 1827 | __dget(alias); | ||
| 1828 | return alias; | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | __d_instantiate(entry, inode); | ||
| 1832 | return NULL; | ||
| 1833 | } | ||
| 1834 | |||
| 1835 | struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | ||
| 1836 | { | ||
| 1837 | struct dentry *result; | ||
| 1838 | |||
| 1839 | BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); | ||
| 1840 | |||
| 1841 | if (inode) | ||
| 1842 | spin_lock(&inode->i_lock); | ||
| 1843 | result = __d_instantiate_unique(entry, inode); | ||
| 1844 | if (inode) | ||
| 1845 | spin_unlock(&inode->i_lock); | ||
| 1846 | |||
| 1847 | if (!result) { | ||
| 1848 | security_d_instantiate(entry, inode); | ||
| 1849 | return NULL; | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | BUG_ON(!d_unhashed(result)); | ||
| 1853 | iput(inode); | ||
| 1854 | return result; | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | EXPORT_SYMBOL(d_instantiate_unique); | ||
| 1858 | |||
| 1859 | /** | ||
| 1860 | * d_instantiate_no_diralias - instantiate a non-aliased dentry | 1784 | * d_instantiate_no_diralias - instantiate a non-aliased dentry |
| 1861 | * @entry: dentry to complete | 1785 | * @entry: dentry to complete |
| 1862 | * @inode: inode to attach to this dentry | 1786 | * @inode: inode to attach to this dentry |
| @@ -2436,6 +2360,86 @@ void d_rehash(struct dentry * entry) | |||
| 2436 | } | 2360 | } |
| 2437 | EXPORT_SYMBOL(d_rehash); | 2361 | EXPORT_SYMBOL(d_rehash); |
| 2438 | 2362 | ||
| 2363 | |||
| 2364 | /* inode->i_lock held if inode is non-NULL */ | ||
| 2365 | |||
| 2366 | static inline void __d_add(struct dentry *dentry, struct inode *inode) | ||
| 2367 | { | ||
| 2368 | if (inode) { | ||
| 2369 | __d_instantiate(dentry, inode); | ||
| 2370 | spin_unlock(&inode->i_lock); | ||
| 2371 | } | ||
| 2372 | security_d_instantiate(dentry, inode); | ||
| 2373 | d_rehash(dentry); | ||
| 2374 | } | ||
| 2375 | |||
| 2376 | /** | ||
| 2377 | * d_add - add dentry to hash queues | ||
| 2378 | * @entry: dentry to add | ||
| 2379 | * @inode: The inode to attach to this dentry | ||
| 2380 | * | ||
| 2381 | * This adds the entry to the hash queues and initializes @inode. | ||
| 2382 | * The entry was actually filled in earlier during d_alloc(). | ||
| 2383 | */ | ||
| 2384 | |||
| 2385 | void d_add(struct dentry *entry, struct inode *inode) | ||
| 2386 | { | ||
| 2387 | if (inode) | ||
| 2388 | spin_lock(&inode->i_lock); | ||
| 2389 | __d_add(entry, inode); | ||
| 2390 | } | ||
| 2391 | EXPORT_SYMBOL(d_add); | ||
| 2392 | |||
| 2393 | /** | ||
| 2394 | * d_exact_alias - find and hash an exact unhashed alias | ||
| 2395 | * @entry: dentry to add | ||
| 2396 | * @inode: The inode to go with this dentry | ||
| 2397 | * | ||
| 2398 | * If an unhashed dentry with the same name/parent and desired | ||
| 2399 | * inode already exists, hash and return it. Otherwise, return | ||
| 2400 | * NULL. | ||
| 2401 | * | ||
| 2402 | * Parent directory should be locked. | ||
| 2403 | */ | ||
| 2404 | struct dentry *d_exact_alias(struct dentry *entry, struct inode *inode) | ||
| 2405 | { | ||
| 2406 | struct dentry *alias; | ||
| 2407 | int len = entry->d_name.len; | ||
| 2408 | const char *name = entry->d_name.name; | ||
| 2409 | unsigned int hash = entry->d_name.hash; | ||
| 2410 | |||
| 2411 | spin_lock(&inode->i_lock); | ||
| 2412 | hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { | ||
| 2413 | /* | ||
| 2414 | * Don't need alias->d_lock here, because aliases with | ||
| 2415 | * d_parent == entry->d_parent are not subject to name or | ||
| 2416 | * parent changes, because the parent inode i_mutex is held. | ||
| 2417 | */ | ||
| 2418 | if (alias->d_name.hash != hash) | ||
| 2419 | continue; | ||
| 2420 | if (alias->d_parent != entry->d_parent) | ||
| 2421 | continue; | ||
| 2422 | if (alias->d_name.len != len) | ||
| 2423 | continue; | ||
| 2424 | if (dentry_cmp(alias, name, len)) | ||
| 2425 | continue; | ||
| 2426 | spin_lock(&alias->d_lock); | ||
| 2427 | if (!d_unhashed(alias)) { | ||
| 2428 | spin_unlock(&alias->d_lock); | ||
| 2429 | alias = NULL; | ||
| 2430 | } else { | ||
| 2431 | __dget_dlock(alias); | ||
| 2432 | _d_rehash(alias); | ||
| 2433 | spin_unlock(&alias->d_lock); | ||
| 2434 | } | ||
| 2435 | spin_unlock(&inode->i_lock); | ||
| 2436 | return alias; | ||
| 2437 | } | ||
| 2438 | spin_unlock(&inode->i_lock); | ||
| 2439 | return NULL; | ||
| 2440 | } | ||
| 2441 | EXPORT_SYMBOL(d_exact_alias); | ||
| 2442 | |||
| 2439 | /** | 2443 | /** |
| 2440 | * dentry_update_name_case - update case insensitive dentry with a new name | 2444 | * dentry_update_name_case - update case insensitive dentry with a new name |
| 2441 | * @dentry: dentry to be updated | 2445 | * @dentry: dentry to be updated |
| @@ -2772,10 +2776,9 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
| 2772 | 2776 | ||
| 2773 | BUG_ON(!d_unhashed(dentry)); | 2777 | BUG_ON(!d_unhashed(dentry)); |
| 2774 | 2778 | ||
| 2775 | if (!inode) { | 2779 | if (!inode) |
| 2776 | __d_instantiate(dentry, NULL); | ||
| 2777 | goto out; | 2780 | goto out; |
| 2778 | } | 2781 | |
| 2779 | spin_lock(&inode->i_lock); | 2782 | spin_lock(&inode->i_lock); |
| 2780 | if (S_ISDIR(inode->i_mode)) { | 2783 | if (S_ISDIR(inode->i_mode)) { |
| 2781 | struct dentry *new = __d_find_any_alias(inode); | 2784 | struct dentry *new = __d_find_any_alias(inode); |
| @@ -2809,12 +2812,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
| 2809 | return new; | 2812 | return new; |
| 2810 | } | 2813 | } |
| 2811 | } | 2814 | } |
| 2812 | /* already taking inode->i_lock, so d_add() by hand */ | ||
| 2813 | __d_instantiate(dentry, inode); | ||
| 2814 | spin_unlock(&inode->i_lock); | ||
| 2815 | out: | 2815 | out: |
| 2816 | security_d_instantiate(dentry, inode); | 2816 | __d_add(dentry, inode); |
| 2817 | d_rehash(dentry); | ||
| 2818 | return NULL; | 2817 | return NULL; |
| 2819 | } | 2818 | } |
| 2820 | EXPORT_SYMBOL(d_splice_alias); | 2819 | EXPORT_SYMBOL(d_splice_alias); |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 1b2f7ffc8b84..85463171053b 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
| @@ -445,7 +445,8 @@ static struct bio *dio_await_one(struct dio *dio) | |||
| 445 | __set_current_state(TASK_UNINTERRUPTIBLE); | 445 | __set_current_state(TASK_UNINTERRUPTIBLE); |
| 446 | dio->waiter = current; | 446 | dio->waiter = current; |
| 447 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 447 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
| 448 | if (!blk_poll(bdev_get_queue(dio->bio_bdev), dio->bio_cookie)) | 448 | if (!(dio->iocb->ki_flags & IOCB_HIPRI) || |
| 449 | !blk_poll(bdev_get_queue(dio->bio_bdev), dio->bio_cookie)) | ||
| 449 | io_schedule(); | 450 | io_schedule(); |
| 450 | /* wake up sets us TASK_RUNNING */ | 451 | /* wake up sets us TASK_RUNNING */ |
| 451 | spin_lock_irqsave(&dio->bio_lock, flags); | 452 | spin_lock_irqsave(&dio->bio_lock, flags); |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 80d6901493cf..87dbdd4881ab 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1499,16 +1499,14 @@ out: | |||
| 1499 | */ | 1499 | */ |
| 1500 | static int | 1500 | static int |
| 1501 | ecryptfs_encrypt_filename(struct ecryptfs_filename *filename, | 1501 | ecryptfs_encrypt_filename(struct ecryptfs_filename *filename, |
| 1502 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1503 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 1502 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
| 1504 | { | 1503 | { |
| 1505 | int rc = 0; | 1504 | int rc = 0; |
| 1506 | 1505 | ||
| 1507 | filename->encrypted_filename = NULL; | 1506 | filename->encrypted_filename = NULL; |
| 1508 | filename->encrypted_filename_size = 0; | 1507 | filename->encrypted_filename_size = 0; |
| 1509 | if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) | 1508 | if (mount_crypt_stat && (mount_crypt_stat->flags |
| 1510 | || (mount_crypt_stat && (mount_crypt_stat->flags | 1509 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK)) { |
| 1511 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { | ||
| 1512 | size_t packet_size; | 1510 | size_t packet_size; |
| 1513 | size_t remaining_bytes; | 1511 | size_t remaining_bytes; |
| 1514 | 1512 | ||
| @@ -1944,7 +1942,6 @@ out: | |||
| 1944 | int ecryptfs_encrypt_and_encode_filename( | 1942 | int ecryptfs_encrypt_and_encode_filename( |
| 1945 | char **encoded_name, | 1943 | char **encoded_name, |
| 1946 | size_t *encoded_name_size, | 1944 | size_t *encoded_name_size, |
| 1947 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1948 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 1945 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 1949 | const char *name, size_t name_size) | 1946 | const char *name, size_t name_size) |
| 1950 | { | 1947 | { |
| @@ -1953,9 +1950,8 @@ int ecryptfs_encrypt_and_encode_filename( | |||
| 1953 | 1950 | ||
| 1954 | (*encoded_name) = NULL; | 1951 | (*encoded_name) = NULL; |
| 1955 | (*encoded_name_size) = 0; | 1952 | (*encoded_name_size) = 0; |
| 1956 | if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) | 1953 | if (mount_crypt_stat && (mount_crypt_stat->flags |
| 1957 | || (mount_crypt_stat && (mount_crypt_stat->flags | 1954 | & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { |
| 1958 | & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) { | ||
| 1959 | struct ecryptfs_filename *filename; | 1955 | struct ecryptfs_filename *filename; |
| 1960 | 1956 | ||
| 1961 | filename = kzalloc(sizeof(*filename), GFP_KERNEL); | 1957 | filename = kzalloc(sizeof(*filename), GFP_KERNEL); |
| @@ -1968,8 +1964,7 @@ int ecryptfs_encrypt_and_encode_filename( | |||
| 1968 | } | 1964 | } |
| 1969 | filename->filename = (char *)name; | 1965 | filename->filename = (char *)name; |
| 1970 | filename->filename_size = name_size; | 1966 | filename->filename_size = name_size; |
| 1971 | rc = ecryptfs_encrypt_filename(filename, crypt_stat, | 1967 | rc = ecryptfs_encrypt_filename(filename, mount_crypt_stat); |
| 1972 | mount_crypt_stat); | ||
| 1973 | if (rc) { | 1968 | if (rc) { |
| 1974 | printk(KERN_ERR "%s: Error attempting to encrypt " | 1969 | printk(KERN_ERR "%s: Error attempting to encrypt " |
| 1975 | "filename; rc = [%d]\n", __func__, rc); | 1970 | "filename; rc = [%d]\n", __func__, rc); |
| @@ -1980,11 +1975,9 @@ int ecryptfs_encrypt_and_encode_filename( | |||
| 1980 | NULL, &encoded_name_no_prefix_size, | 1975 | NULL, &encoded_name_no_prefix_size, |
| 1981 | filename->encrypted_filename, | 1976 | filename->encrypted_filename, |
| 1982 | filename->encrypted_filename_size); | 1977 | filename->encrypted_filename_size); |
| 1983 | if ((crypt_stat && (crypt_stat->flags | 1978 | if (mount_crypt_stat |
| 1984 | & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) | ||
| 1985 | || (mount_crypt_stat | ||
| 1986 | && (mount_crypt_stat->flags | 1979 | && (mount_crypt_stat->flags |
| 1987 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) | 1980 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK)) |
| 1988 | (*encoded_name_size) = | 1981 | (*encoded_name_size) = |
| 1989 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE | 1982 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE |
| 1990 | + encoded_name_no_prefix_size); | 1983 | + encoded_name_no_prefix_size); |
| @@ -2002,11 +1995,9 @@ int ecryptfs_encrypt_and_encode_filename( | |||
| 2002 | kfree(filename); | 1995 | kfree(filename); |
| 2003 | goto out; | 1996 | goto out; |
| 2004 | } | 1997 | } |
| 2005 | if ((crypt_stat && (crypt_stat->flags | 1998 | if (mount_crypt_stat |
| 2006 | & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) | ||
| 2007 | || (mount_crypt_stat | ||
| 2008 | && (mount_crypt_stat->flags | 1999 | && (mount_crypt_stat->flags |
| 2009 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { | 2000 | & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK)) { |
| 2010 | memcpy((*encoded_name), | 2001 | memcpy((*encoded_name), |
| 2011 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | 2002 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, |
| 2012 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE); | 2003 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 7b39260c7bba..67e16128c572 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -569,7 +569,6 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | |||
| 569 | int ecryptfs_encrypt_and_encode_filename( | 569 | int ecryptfs_encrypt_and_encode_filename( |
| 570 | char **encoded_name, | 570 | char **encoded_name, |
| 571 | size_t *encoded_name_size, | 571 | size_t *encoded_name_size, |
| 572 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 573 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 572 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 574 | const char *name, size_t name_size); | 573 | const char *name, size_t name_size); |
| 575 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); | 574 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 4e685ac1024d..26651636cd1d 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -397,11 +397,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 397 | int rc = 0; | 397 | int rc = 0; |
| 398 | 398 | ||
| 399 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 399 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
| 400 | inode_lock(d_inode(lower_dir_dentry)); | 400 | lower_dentry = lookup_one_len_unlocked(ecryptfs_dentry->d_name.name, |
| 401 | lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, | ||
| 402 | lower_dir_dentry, | 401 | lower_dir_dentry, |
| 403 | ecryptfs_dentry->d_name.len); | 402 | ecryptfs_dentry->d_name.len); |
| 404 | inode_unlock(d_inode(lower_dir_dentry)); | ||
| 405 | if (IS_ERR(lower_dentry)) { | 403 | if (IS_ERR(lower_dentry)) { |
| 406 | rc = PTR_ERR(lower_dentry); | 404 | rc = PTR_ERR(lower_dentry); |
| 407 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 405 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
| @@ -419,18 +417,16 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 419 | dput(lower_dentry); | 417 | dput(lower_dentry); |
| 420 | rc = ecryptfs_encrypt_and_encode_filename( | 418 | rc = ecryptfs_encrypt_and_encode_filename( |
| 421 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, | 419 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, |
| 422 | NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, | 420 | mount_crypt_stat, ecryptfs_dentry->d_name.name, |
| 423 | ecryptfs_dentry->d_name.len); | 421 | ecryptfs_dentry->d_name.len); |
| 424 | if (rc) { | 422 | if (rc) { |
| 425 | printk(KERN_ERR "%s: Error attempting to encrypt and encode " | 423 | printk(KERN_ERR "%s: Error attempting to encrypt and encode " |
| 426 | "filename; rc = [%d]\n", __func__, rc); | 424 | "filename; rc = [%d]\n", __func__, rc); |
| 427 | goto out; | 425 | goto out; |
| 428 | } | 426 | } |
| 429 | inode_lock(d_inode(lower_dir_dentry)); | 427 | lower_dentry = lookup_one_len_unlocked(encrypted_and_encoded_name, |
| 430 | lower_dentry = lookup_one_len(encrypted_and_encoded_name, | ||
| 431 | lower_dir_dentry, | 428 | lower_dir_dentry, |
| 432 | encrypted_and_encoded_name_size); | 429 | encrypted_and_encoded_name_size); |
| 433 | inode_unlock(d_inode(lower_dir_dentry)); | ||
| 434 | if (IS_ERR(lower_dentry)) { | 430 | if (IS_ERR(lower_dentry)) { |
| 435 | rc = PTR_ERR(lower_dentry); | 431 | rc = PTR_ERR(lower_dentry); |
| 436 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " | 432 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
| @@ -502,7 +498,6 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 502 | dir->i_sb)->mount_crypt_stat; | 498 | dir->i_sb)->mount_crypt_stat; |
| 503 | rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, | 499 | rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, |
| 504 | &encoded_symlen, | 500 | &encoded_symlen, |
| 505 | NULL, | ||
| 506 | mount_crypt_stat, symname, | 501 | mount_crypt_stat, symname, |
| 507 | strlen(symname)); | 502 | strlen(symname)); |
| 508 | if (rc) | 503 | if (rc) |
diff --git a/fs/namei.c b/fs/namei.c index 9c590e0f66e9..794f81dce766 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1220,8 +1220,8 @@ static int follow_managed(struct path *path, struct nameidata *nd) | |||
| 1220 | 1220 | ||
| 1221 | if (need_mntput && path->mnt == mnt) | 1221 | if (need_mntput && path->mnt == mnt) |
| 1222 | mntput(path->mnt); | 1222 | mntput(path->mnt); |
| 1223 | if (ret == -EISDIR) | 1223 | if (ret == -EISDIR || !ret) |
| 1224 | ret = 0; | 1224 | ret = 1; |
| 1225 | if (need_mntput) | 1225 | if (need_mntput) |
| 1226 | nd->flags |= LOOKUP_JUMPED; | 1226 | nd->flags |= LOOKUP_JUMPED; |
| 1227 | if (unlikely(ret < 0)) | 1227 | if (unlikely(ret < 0)) |
| @@ -1444,40 +1444,26 @@ static int follow_dotdot(struct nameidata *nd) | |||
| 1444 | * This looks up the name in dcache, possibly revalidates the old dentry and | 1444 | * This looks up the name in dcache, possibly revalidates the old dentry and |
| 1445 | * allocates a new one if not found or not valid. In the need_lookup argument | 1445 | * allocates a new one if not found or not valid. In the need_lookup argument |
| 1446 | * returns whether i_op->lookup is necessary. | 1446 | * returns whether i_op->lookup is necessary. |
| 1447 | * | ||
| 1448 | * dir->d_inode->i_mutex must be held | ||
| 1449 | */ | 1447 | */ |
| 1450 | static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | 1448 | static struct dentry *lookup_dcache(const struct qstr *name, |
| 1451 | unsigned int flags, bool *need_lookup) | 1449 | struct dentry *dir, |
| 1450 | unsigned int flags) | ||
| 1452 | { | 1451 | { |
| 1453 | struct dentry *dentry; | 1452 | struct dentry *dentry; |
| 1454 | int error; | 1453 | int error; |
| 1455 | 1454 | ||
| 1456 | *need_lookup = false; | ||
| 1457 | dentry = d_lookup(dir, name); | 1455 | dentry = d_lookup(dir, name); |
| 1458 | if (dentry) { | 1456 | if (dentry) { |
| 1459 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) { | 1457 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) { |
| 1460 | error = d_revalidate(dentry, flags); | 1458 | error = d_revalidate(dentry, flags); |
| 1461 | if (unlikely(error <= 0)) { | 1459 | if (unlikely(error <= 0)) { |
| 1462 | if (error < 0) { | 1460 | if (!error) |
| 1463 | dput(dentry); | ||
| 1464 | return ERR_PTR(error); | ||
| 1465 | } else { | ||
| 1466 | d_invalidate(dentry); | 1461 | d_invalidate(dentry); |
| 1467 | dput(dentry); | 1462 | dput(dentry); |
| 1468 | dentry = NULL; | 1463 | return ERR_PTR(error); |
| 1469 | } | ||
| 1470 | } | 1464 | } |
| 1471 | } | 1465 | } |
| 1472 | } | 1466 | } |
| 1473 | |||
| 1474 | if (!dentry) { | ||
| 1475 | dentry = d_alloc(dir, name); | ||
| 1476 | if (unlikely(!dentry)) | ||
| 1477 | return ERR_PTR(-ENOMEM); | ||
| 1478 | |||
| 1479 | *need_lookup = true; | ||
| 1480 | } | ||
| 1481 | return dentry; | 1467 | return dentry; |
| 1482 | } | 1468 | } |
| 1483 | 1469 | ||
| @@ -1506,45 +1492,44 @@ static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, | |||
| 1506 | return dentry; | 1492 | return dentry; |
| 1507 | } | 1493 | } |
| 1508 | 1494 | ||
| 1509 | static struct dentry *__lookup_hash(struct qstr *name, | 1495 | static struct dentry *__lookup_hash(const struct qstr *name, |
| 1510 | struct dentry *base, unsigned int flags) | 1496 | struct dentry *base, unsigned int flags) |
| 1511 | { | 1497 | { |
| 1512 | bool need_lookup; | 1498 | struct dentry *dentry = lookup_dcache(name, base, flags); |
| 1513 | struct dentry *dentry; | ||
| 1514 | 1499 | ||
| 1515 | dentry = lookup_dcache(name, base, flags, &need_lookup); | 1500 | if (dentry) |
| 1516 | if (!need_lookup) | ||
| 1517 | return dentry; | 1501 | return dentry; |
| 1518 | 1502 | ||
| 1503 | dentry = d_alloc(base, name); | ||
| 1504 | if (unlikely(!dentry)) | ||
| 1505 | return ERR_PTR(-ENOMEM); | ||
| 1506 | |||
| 1519 | return lookup_real(base->d_inode, dentry, flags); | 1507 | return lookup_real(base->d_inode, dentry, flags); |
| 1520 | } | 1508 | } |
| 1521 | 1509 | ||
| 1522 | /* | ||
| 1523 | * It's more convoluted than I'd like it to be, but... it's still fairly | ||
| 1524 | * small and for now I'd prefer to have fast path as straight as possible. | ||
| 1525 | * It _is_ time-critical. | ||
| 1526 | */ | ||
| 1527 | static int lookup_fast(struct nameidata *nd, | 1510 | static int lookup_fast(struct nameidata *nd, |
| 1528 | struct path *path, struct inode **inode, | 1511 | struct path *path, struct inode **inode, |
| 1529 | unsigned *seqp) | 1512 | unsigned *seqp) |
| 1530 | { | 1513 | { |
| 1531 | struct vfsmount *mnt = nd->path.mnt; | 1514 | struct vfsmount *mnt = nd->path.mnt; |
| 1532 | struct dentry *dentry, *parent = nd->path.dentry; | 1515 | struct dentry *dentry, *parent = nd->path.dentry; |
| 1533 | int need_reval = 1; | ||
| 1534 | int status = 1; | 1516 | int status = 1; |
| 1535 | int err; | 1517 | int err; |
| 1536 | 1518 | ||
| 1537 | /* | 1519 | /* |
| 1538 | * Rename seqlock is not required here because in the off chance | 1520 | * Rename seqlock is not required here because in the off chance |
| 1539 | * of a false negative due to a concurrent rename, we're going to | 1521 | * of a false negative due to a concurrent rename, the caller is |
| 1540 | * do the non-racy lookup, below. | 1522 | * going to fall back to non-racy lookup. |
| 1541 | */ | 1523 | */ |
| 1542 | if (nd->flags & LOOKUP_RCU) { | 1524 | if (nd->flags & LOOKUP_RCU) { |
| 1543 | unsigned seq; | 1525 | unsigned seq; |
| 1544 | bool negative; | 1526 | bool negative; |
| 1545 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); | 1527 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); |
| 1546 | if (!dentry) | 1528 | if (unlikely(!dentry)) { |
| 1547 | goto unlazy; | 1529 | if (unlazy_walk(nd, NULL, 0)) |
| 1530 | return -ECHILD; | ||
| 1531 | return 0; | ||
| 1532 | } | ||
| 1548 | 1533 | ||
| 1549 | /* | 1534 | /* |
| 1550 | * This sequence count validates that the inode matches | 1535 | * This sequence count validates that the inode matches |
| @@ -1552,7 +1537,7 @@ static int lookup_fast(struct nameidata *nd, | |||
| 1552 | */ | 1537 | */ |
| 1553 | *inode = d_backing_inode(dentry); | 1538 | *inode = d_backing_inode(dentry); |
| 1554 | negative = d_is_negative(dentry); | 1539 | negative = d_is_negative(dentry); |
| 1555 | if (read_seqcount_retry(&dentry->d_seq, seq)) | 1540 | if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) |
| 1556 | return -ECHILD; | 1541 | return -ECHILD; |
| 1557 | 1542 | ||
| 1558 | /* | 1543 | /* |
| @@ -1562,81 +1547,89 @@ static int lookup_fast(struct nameidata *nd, | |||
| 1562 | * The memory barrier in read_seqcount_begin of child is | 1547 | * The memory barrier in read_seqcount_begin of child is |
| 1563 | * enough, we can use __read_seqcount_retry here. | 1548 | * enough, we can use __read_seqcount_retry here. |
| 1564 | */ | 1549 | */ |
| 1565 | if (__read_seqcount_retry(&parent->d_seq, nd->seq)) | 1550 | if (unlikely(__read_seqcount_retry(&parent->d_seq, nd->seq))) |
| 1566 | return -ECHILD; | 1551 | return -ECHILD; |
| 1567 | 1552 | ||
| 1568 | *seqp = seq; | 1553 | *seqp = seq; |
| 1569 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { | 1554 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) |
| 1570 | status = d_revalidate(dentry, nd->flags); | 1555 | status = d_revalidate(dentry, nd->flags); |
| 1571 | if (unlikely(status <= 0)) { | 1556 | if (unlikely(status <= 0)) { |
| 1572 | if (status != -ECHILD) | 1557 | if (unlazy_walk(nd, dentry, seq)) |
| 1573 | need_reval = 0; | 1558 | return -ECHILD; |
| 1574 | goto unlazy; | 1559 | if (status == -ECHILD) |
| 1575 | } | 1560 | status = d_revalidate(dentry, nd->flags); |
| 1561 | } else { | ||
| 1562 | /* | ||
| 1563 | * Note: do negative dentry check after revalidation in | ||
| 1564 | * case that drops it. | ||
| 1565 | */ | ||
| 1566 | if (unlikely(negative)) | ||
| 1567 | return -ENOENT; | ||
| 1568 | path->mnt = mnt; | ||
| 1569 | path->dentry = dentry; | ||
| 1570 | if (likely(__follow_mount_rcu(nd, path, inode, seqp))) | ||
| 1571 | return 1; | ||
| 1572 | if (unlazy_walk(nd, dentry, seq)) | ||
| 1573 | return -ECHILD; | ||
| 1576 | } | 1574 | } |
| 1577 | /* | ||
| 1578 | * Note: do negative dentry check after revalidation in | ||
| 1579 | * case that drops it. | ||
| 1580 | */ | ||
| 1581 | if (negative) | ||
| 1582 | return -ENOENT; | ||
| 1583 | path->mnt = mnt; | ||
| 1584 | path->dentry = dentry; | ||
| 1585 | if (likely(__follow_mount_rcu(nd, path, inode, seqp))) | ||
| 1586 | return 0; | ||
| 1587 | unlazy: | ||
| 1588 | if (unlazy_walk(nd, dentry, seq)) | ||
| 1589 | return -ECHILD; | ||
| 1590 | } else { | 1575 | } else { |
| 1591 | dentry = __d_lookup(parent, &nd->last); | 1576 | dentry = __d_lookup(parent, &nd->last); |
| 1577 | if (unlikely(!dentry)) | ||
| 1578 | return 0; | ||
| 1579 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) | ||
| 1580 | status = d_revalidate(dentry, nd->flags); | ||
| 1592 | } | 1581 | } |
| 1593 | |||
| 1594 | if (unlikely(!dentry)) | ||
| 1595 | goto need_lookup; | ||
| 1596 | |||
| 1597 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) | ||
| 1598 | status = d_revalidate(dentry, nd->flags); | ||
| 1599 | if (unlikely(status <= 0)) { | 1582 | if (unlikely(status <= 0)) { |
| 1600 | if (status < 0) { | 1583 | if (!status) |
| 1601 | dput(dentry); | 1584 | d_invalidate(dentry); |
| 1602 | return status; | ||
| 1603 | } | ||
| 1604 | d_invalidate(dentry); | ||
| 1605 | dput(dentry); | 1585 | dput(dentry); |
| 1606 | goto need_lookup; | 1586 | return status; |
| 1607 | } | 1587 | } |
| 1608 | |||
| 1609 | if (unlikely(d_is_negative(dentry))) { | 1588 | if (unlikely(d_is_negative(dentry))) { |
| 1610 | dput(dentry); | 1589 | dput(dentry); |
| 1611 | return -ENOENT; | 1590 | return -ENOENT; |
| 1612 | } | 1591 | } |
| 1592 | |||
| 1613 | path->mnt = mnt; | 1593 | path->mnt = mnt; |
| 1614 | path->dentry = dentry; | 1594 | path->dentry = dentry; |
| 1615 | err = follow_managed(path, nd); | 1595 | err = follow_managed(path, nd); |
| 1616 | if (likely(!err)) | 1596 | if (likely(err > 0)) |
| 1617 | *inode = d_backing_inode(path->dentry); | 1597 | *inode = d_backing_inode(path->dentry); |
| 1618 | return err; | 1598 | return err; |
| 1619 | |||
| 1620 | need_lookup: | ||
| 1621 | return 1; | ||
| 1622 | } | 1599 | } |
| 1623 | 1600 | ||
| 1624 | /* Fast lookup failed, do it the slow way */ | 1601 | /* Fast lookup failed, do it the slow way */ |
| 1625 | static int lookup_slow(struct nameidata *nd, struct path *path) | 1602 | static struct dentry *lookup_slow(const struct qstr *name, |
| 1603 | struct dentry *dir, | ||
| 1604 | unsigned int flags) | ||
| 1626 | { | 1605 | { |
| 1627 | struct dentry *dentry, *parent; | 1606 | struct dentry *dentry; |
| 1628 | 1607 | inode_lock(dir->d_inode); | |
| 1629 | parent = nd->path.dentry; | 1608 | dentry = d_lookup(dir, name); |
| 1630 | BUG_ON(nd->inode != parent->d_inode); | 1609 | if (unlikely(dentry)) { |
| 1631 | 1610 | if ((dentry->d_flags & DCACHE_OP_REVALIDATE) && | |
| 1632 | inode_lock(parent->d_inode); | 1611 | !(flags & LOOKUP_NO_REVAL)) { |
| 1633 | dentry = __lookup_hash(&nd->last, parent, nd->flags); | 1612 | int error = d_revalidate(dentry, flags); |
| 1634 | inode_unlock(parent->d_inode); | 1613 | if (unlikely(error <= 0)) { |
| 1635 | if (IS_ERR(dentry)) | 1614 | if (!error) |
| 1636 | return PTR_ERR(dentry); | 1615 | d_invalidate(dentry); |
| 1637 | path->mnt = nd->path.mnt; | 1616 | dput(dentry); |
| 1638 | path->dentry = dentry; | 1617 | dentry = ERR_PTR(error); |
| 1639 | return follow_managed(path, nd); | 1618 | } |
| 1619 | } | ||
| 1620 | if (dentry) { | ||
| 1621 | inode_unlock(dir->d_inode); | ||
| 1622 | return dentry; | ||
| 1623 | } | ||
| 1624 | } | ||
| 1625 | dentry = d_alloc(dir, name); | ||
| 1626 | if (unlikely(!dentry)) { | ||
| 1627 | inode_unlock(dir->d_inode); | ||
| 1628 | return ERR_PTR(-ENOMEM); | ||
| 1629 | } | ||
| 1630 | dentry = lookup_real(dir->d_inode, dentry, flags); | ||
| 1631 | inode_unlock(dir->d_inode); | ||
| 1632 | return dentry; | ||
| 1640 | } | 1633 | } |
| 1641 | 1634 | ||
| 1642 | static inline int may_lookup(struct nameidata *nd) | 1635 | static inline int may_lookup(struct nameidata *nd) |
| @@ -1740,18 +1733,23 @@ static int walk_component(struct nameidata *nd, int flags) | |||
| 1740 | return err; | 1733 | return err; |
| 1741 | } | 1734 | } |
| 1742 | err = lookup_fast(nd, &path, &inode, &seq); | 1735 | err = lookup_fast(nd, &path, &inode, &seq); |
| 1743 | if (unlikely(err)) { | 1736 | if (unlikely(err <= 0)) { |
| 1744 | if (err < 0) | 1737 | if (err < 0) |
| 1745 | return err; | 1738 | return err; |
| 1746 | 1739 | path.dentry = lookup_slow(&nd->last, nd->path.dentry, | |
| 1747 | err = lookup_slow(nd, &path); | 1740 | nd->flags); |
| 1748 | if (err < 0) | 1741 | if (IS_ERR(path.dentry)) |
| 1742 | return PTR_ERR(path.dentry); | ||
| 1743 | if (unlikely(d_is_negative(path.dentry))) { | ||
| 1744 | dput(path.dentry); | ||
| 1745 | return -ENOENT; | ||
| 1746 | } | ||
| 1747 | path.mnt = nd->path.mnt; | ||
| 1748 | err = follow_managed(&path, nd); | ||
| 1749 | if (unlikely(err < 0)) | ||
| 1749 | return err; | 1750 | return err; |
| 1750 | 1751 | ||
| 1751 | seq = 0; /* we are already out of RCU mode */ | 1752 | seq = 0; /* we are already out of RCU mode */ |
| 1752 | err = -ENOENT; | ||
| 1753 | if (d_is_negative(path.dentry)) | ||
| 1754 | goto out_path_put; | ||
| 1755 | inode = d_backing_inode(path.dentry); | 1753 | inode = d_backing_inode(path.dentry); |
| 1756 | } | 1754 | } |
| 1757 | 1755 | ||
| @@ -1764,10 +1762,6 @@ static int walk_component(struct nameidata *nd, int flags) | |||
| 1764 | nd->inode = inode; | 1762 | nd->inode = inode; |
| 1765 | nd->seq = seq; | 1763 | nd->seq = seq; |
| 1766 | return 0; | 1764 | return 0; |
| 1767 | |||
| 1768 | out_path_put: | ||
| 1769 | path_to_nameidata(&path, nd); | ||
| 1770 | return err; | ||
| 1771 | } | 1765 | } |
| 1772 | 1766 | ||
| 1773 | /* | 1767 | /* |
| @@ -2373,21 +2367,9 @@ struct dentry *lookup_one_len_unlocked(const char *name, | |||
| 2373 | if (err) | 2367 | if (err) |
| 2374 | return ERR_PTR(err); | 2368 | return ERR_PTR(err); |
| 2375 | 2369 | ||
| 2376 | /* | 2370 | ret = lookup_dcache(&this, base, 0); |
| 2377 | * __d_lookup() is used to try to get a quick answer and avoid the | 2371 | if (!ret) |
| 2378 | * mutex. A false-negative does no harm. | 2372 | ret = lookup_slow(&this, base, 0); |
| 2379 | */ | ||
| 2380 | ret = __d_lookup(base, &this); | ||
| 2381 | if (ret && unlikely(ret->d_flags & DCACHE_OP_REVALIDATE)) { | ||
| 2382 | dput(ret); | ||
| 2383 | ret = NULL; | ||
| 2384 | } | ||
| 2385 | if (ret) | ||
| 2386 | return ret; | ||
| 2387 | |||
| 2388 | inode_lock(base->d_inode); | ||
| 2389 | ret = __lookup_hash(&this, base, 0); | ||
| 2390 | inode_unlock(base->d_inode); | ||
| 2391 | return ret; | 2373 | return ret; |
| 2392 | } | 2374 | } |
| 2393 | EXPORT_SYMBOL(lookup_one_len_unlocked); | 2375 | EXPORT_SYMBOL(lookup_one_len_unlocked); |
| @@ -2465,31 +2447,21 @@ mountpoint_last(struct nameidata *nd, struct path *path) | |||
| 2465 | if (error) | 2447 | if (error) |
| 2466 | return error; | 2448 | return error; |
| 2467 | dentry = dget(nd->path.dentry); | 2449 | dentry = dget(nd->path.dentry); |
| 2468 | goto done; | 2450 | } else { |
| 2469 | } | 2451 | dentry = d_lookup(dir, &nd->last); |
| 2470 | |||
| 2471 | inode_lock(dir->d_inode); | ||
| 2472 | dentry = d_lookup(dir, &nd->last); | ||
| 2473 | if (!dentry) { | ||
| 2474 | /* | ||
| 2475 | * No cached dentry. Mounted dentries are pinned in the cache, | ||
| 2476 | * so that means that this dentry is probably a symlink or the | ||
| 2477 | * path doesn't actually point to a mounted dentry. | ||
| 2478 | */ | ||
| 2479 | dentry = d_alloc(dir, &nd->last); | ||
| 2480 | if (!dentry) { | 2452 | if (!dentry) { |
| 2481 | inode_unlock(dir->d_inode); | 2453 | /* |
| 2482 | return -ENOMEM; | 2454 | * No cached dentry. Mounted dentries are pinned in the |
| 2483 | } | 2455 | * cache, so that means that this dentry is probably |
| 2484 | dentry = lookup_real(dir->d_inode, dentry, nd->flags); | 2456 | * a symlink or the path doesn't actually point |
| 2485 | if (IS_ERR(dentry)) { | 2457 | * to a mounted dentry. |
| 2486 | inode_unlock(dir->d_inode); | 2458 | */ |
| 2487 | return PTR_ERR(dentry); | 2459 | dentry = lookup_slow(&nd->last, dir, |
| 2460 | nd->flags | LOOKUP_NO_REVAL); | ||
| 2461 | if (IS_ERR(dentry)) | ||
| 2462 | return PTR_ERR(dentry); | ||
| 2488 | } | 2463 | } |
| 2489 | } | 2464 | } |
| 2490 | inode_unlock(dir->d_inode); | ||
| 2491 | |||
| 2492 | done: | ||
| 2493 | if (d_is_negative(dentry)) { | 2465 | if (d_is_negative(dentry)) { |
| 2494 | dput(dentry); | 2466 | dput(dentry); |
| 2495 | return -ENOENT; | 2467 | return -ENOENT; |
| @@ -3018,16 +2990,22 @@ static int lookup_open(struct nameidata *nd, struct path *path, | |||
| 3018 | struct inode *dir_inode = dir->d_inode; | 2990 | struct inode *dir_inode = dir->d_inode; |
| 3019 | struct dentry *dentry; | 2991 | struct dentry *dentry; |
| 3020 | int error; | 2992 | int error; |
| 3021 | bool need_lookup; | 2993 | bool need_lookup = false; |
| 3022 | 2994 | ||
| 3023 | *opened &= ~FILE_CREATED; | 2995 | *opened &= ~FILE_CREATED; |
| 3024 | dentry = lookup_dcache(&nd->last, dir, nd->flags, &need_lookup); | 2996 | dentry = lookup_dcache(&nd->last, dir, nd->flags); |
| 3025 | if (IS_ERR(dentry)) | 2997 | if (IS_ERR(dentry)) |
| 3026 | return PTR_ERR(dentry); | 2998 | return PTR_ERR(dentry); |
| 3027 | 2999 | ||
| 3028 | /* Cached positive dentry: will open in f_op->open */ | 3000 | if (!dentry) { |
| 3029 | if (!need_lookup && dentry->d_inode) | 3001 | dentry = d_alloc(dir, &nd->last); |
| 3002 | if (unlikely(!dentry)) | ||
| 3003 | return -ENOMEM; | ||
| 3004 | need_lookup = true; | ||
| 3005 | } else if (dentry->d_inode) { | ||
| 3006 | /* Cached positive dentry: will open in f_op->open */ | ||
| 3030 | goto out_no_open; | 3007 | goto out_no_open; |
| 3008 | } | ||
| 3031 | 3009 | ||
| 3032 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { | 3010 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { |
| 3033 | return atomic_open(nd, dentry, path, file, op, got_write, | 3011 | return atomic_open(nd, dentry, path, file, op, got_write, |
| @@ -3111,13 +3089,14 @@ static int do_last(struct nameidata *nd, | |||
| 3111 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; | 3089 | nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; |
| 3112 | /* we _can_ be in RCU mode here */ | 3090 | /* we _can_ be in RCU mode here */ |
| 3113 | error = lookup_fast(nd, &path, &inode, &seq); | 3091 | error = lookup_fast(nd, &path, &inode, &seq); |
| 3114 | if (likely(!error)) | 3092 | if (likely(error > 0)) |
| 3115 | goto finish_lookup; | 3093 | goto finish_lookup; |
| 3116 | 3094 | ||
| 3117 | if (error < 0) | 3095 | if (error < 0) |
| 3118 | return error; | 3096 | return error; |
| 3119 | 3097 | ||
| 3120 | BUG_ON(nd->inode != dir->d_inode); | 3098 | BUG_ON(nd->inode != dir->d_inode); |
| 3099 | BUG_ON(nd->flags & LOOKUP_RCU); | ||
| 3121 | } else { | 3100 | } else { |
| 3122 | /* create side of things */ | 3101 | /* create side of things */ |
| 3123 | /* | 3102 | /* |
| @@ -3172,12 +3151,6 @@ retry_lookup: | |||
| 3172 | } | 3151 | } |
| 3173 | 3152 | ||
| 3174 | /* | 3153 | /* |
| 3175 | * create/update audit record if it already exists. | ||
| 3176 | */ | ||
| 3177 | if (d_is_positive(path.dentry)) | ||
| 3178 | audit_inode(nd->name, path.dentry, 0); | ||
| 3179 | |||
| 3180 | /* | ||
| 3181 | * If atomic_open() acquired write access it is dropped now due to | 3154 | * If atomic_open() acquired write access it is dropped now due to |
| 3182 | * possible mount and symlink following (this might be optimized away if | 3155 | * possible mount and symlink following (this might be optimized away if |
| 3183 | * necessary...) | 3156 | * necessary...) |
| @@ -3187,6 +3160,16 @@ retry_lookup: | |||
| 3187 | got_write = false; | 3160 | got_write = false; |
| 3188 | } | 3161 | } |
| 3189 | 3162 | ||
| 3163 | if (unlikely(d_is_negative(path.dentry))) { | ||
| 3164 | path_to_nameidata(&path, nd); | ||
| 3165 | return -ENOENT; | ||
| 3166 | } | ||
| 3167 | |||
| 3168 | /* | ||
| 3169 | * create/update audit record if it already exists. | ||
| 3170 | */ | ||
| 3171 | audit_inode(nd->name, path.dentry, 0); | ||
| 3172 | |||
| 3190 | if (unlikely((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) { | 3173 | if (unlikely((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT))) { |
| 3191 | path_to_nameidata(&path, nd); | 3174 | path_to_nameidata(&path, nd); |
| 3192 | return -EEXIST; | 3175 | return -EEXIST; |
| @@ -3196,12 +3179,7 @@ retry_lookup: | |||
| 3196 | if (unlikely(error < 0)) | 3179 | if (unlikely(error < 0)) |
| 3197 | return error; | 3180 | return error; |
| 3198 | 3181 | ||
| 3199 | BUG_ON(nd->flags & LOOKUP_RCU); | ||
| 3200 | seq = 0; /* out of RCU mode, so the value doesn't matter */ | 3182 | seq = 0; /* out of RCU mode, so the value doesn't matter */ |
| 3201 | if (unlikely(d_is_negative(path.dentry))) { | ||
| 3202 | path_to_nameidata(&path, nd); | ||
| 3203 | return -ENOENT; | ||
| 3204 | } | ||
| 3205 | inode = d_backing_inode(path.dentry); | 3183 | inode = d_backing_inode(path.dentry); |
| 3206 | finish_lookup: | 3184 | finish_lookup: |
| 3207 | if (nd->depth) | 3185 | if (nd->depth) |
| @@ -3707,31 +3685,6 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) | |||
| 3707 | return sys_mkdirat(AT_FDCWD, pathname, mode); | 3685 | return sys_mkdirat(AT_FDCWD, pathname, mode); |
| 3708 | } | 3686 | } |
| 3709 | 3687 | ||
| 3710 | /* | ||
| 3711 | * The dentry_unhash() helper will try to drop the dentry early: we | ||
| 3712 | * should have a usage count of 1 if we're the only user of this | ||
| 3713 | * dentry, and if that is true (possibly after pruning the dcache), | ||
| 3714 | * then we drop the dentry now. | ||
| 3715 | * | ||
| 3716 | * A low-level filesystem can, if it choses, legally | ||
| 3717 | * do a | ||
| 3718 | * | ||
| 3719 | * if (!d_unhashed(dentry)) | ||
| 3720 | * return -EBUSY; | ||
| 3721 | * | ||
| 3722 | * if it cannot handle the case of removing a directory | ||
| 3723 | * that is still in use by something else.. | ||
| 3724 | */ | ||
| 3725 | void dentry_unhash(struct dentry *dentry) | ||
| 3726 | { | ||
| 3727 | shrink_dcache_parent(dentry); | ||
| 3728 | spin_lock(&dentry->d_lock); | ||
| 3729 | if (dentry->d_lockref.count == 1) | ||
| 3730 | __d_drop(dentry); | ||
| 3731 | spin_unlock(&dentry->d_lock); | ||
| 3732 | } | ||
| 3733 | EXPORT_SYMBOL(dentry_unhash); | ||
| 3734 | |||
| 3735 | int vfs_rmdir(struct inode *dir, struct dentry *dentry) | 3688 | int vfs_rmdir(struct inode *dir, struct dentry *dentry) |
| 3736 | { | 3689 | { |
| 3737 | int error = may_delete(dir, dentry, 1); | 3690 | int error = may_delete(dir, dentry, 1); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 9cce67043f92..4bfa7d8bcade 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1360,19 +1360,15 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in | |||
| 1360 | dfprintk(VFS, "NFS: lookup(%pd2)\n", dentry); | 1360 | dfprintk(VFS, "NFS: lookup(%pd2)\n", dentry); |
| 1361 | nfs_inc_stats(dir, NFSIOS_VFSLOOKUP); | 1361 | nfs_inc_stats(dir, NFSIOS_VFSLOOKUP); |
| 1362 | 1362 | ||
| 1363 | res = ERR_PTR(-ENAMETOOLONG); | 1363 | if (unlikely(dentry->d_name.len > NFS_SERVER(dir)->namelen)) |
| 1364 | if (dentry->d_name.len > NFS_SERVER(dir)->namelen) | 1364 | return ERR_PTR(-ENAMETOOLONG); |
| 1365 | goto out; | ||
| 1366 | 1365 | ||
| 1367 | /* | 1366 | /* |
| 1368 | * If we're doing an exclusive create, optimize away the lookup | 1367 | * If we're doing an exclusive create, optimize away the lookup |
| 1369 | * but don't hash the dentry. | 1368 | * but don't hash the dentry. |
| 1370 | */ | 1369 | */ |
| 1371 | if (nfs_is_exclusive_create(dir, flags)) { | 1370 | if (nfs_is_exclusive_create(dir, flags)) |
| 1372 | d_instantiate(dentry, NULL); | 1371 | return NULL; |
| 1373 | res = NULL; | ||
| 1374 | goto out; | ||
| 1375 | } | ||
| 1376 | 1372 | ||
| 1377 | res = ERR_PTR(-ENOMEM); | 1373 | res = ERR_PTR(-ENOMEM); |
| 1378 | fhandle = nfs_alloc_fhandle(); | 1374 | fhandle = nfs_alloc_fhandle(); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4bfc33ad0563..400a70b3be7b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -2461,14 +2461,15 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | |||
| 2461 | 2461 | ||
| 2462 | dentry = opendata->dentry; | 2462 | dentry = opendata->dentry; |
| 2463 | if (d_really_is_negative(dentry)) { | 2463 | if (d_really_is_negative(dentry)) { |
| 2464 | /* FIXME: Is this d_drop() ever needed? */ | 2464 | struct dentry *alias; |
| 2465 | d_drop(dentry); | 2465 | d_drop(dentry); |
| 2466 | dentry = d_add_unique(dentry, igrab(state->inode)); | 2466 | alias = d_exact_alias(dentry, state->inode); |
| 2467 | if (dentry == NULL) { | 2467 | if (!alias) |
| 2468 | dentry = opendata->dentry; | 2468 | alias = d_splice_alias(igrab(state->inode), dentry); |
| 2469 | } else if (dentry != ctx->dentry) { | 2469 | /* d_splice_alias() can't fail here - it's a non-directory */ |
| 2470 | if (alias) { | ||
| 2470 | dput(ctx->dentry); | 2471 | dput(ctx->dentry); |
| 2471 | ctx->dentry = dget(dentry); | 2472 | ctx->dentry = dentry = alias; |
| 2472 | } | 2473 | } |
| 2473 | nfs_set_verifier(dentry, | 2474 | nfs_set_verifier(dentry, |
| 2474 | nfs_save_change_attribute(d_inode(opendata->dir))); | 2475 | nfs_save_change_attribute(d_inode(opendata->dir))); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 5d2a57e4c03a..d40010e4f1a9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -870,7 +870,7 @@ __be32 nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen, | |||
| 870 | 870 | ||
| 871 | oldfs = get_fs(); | 871 | oldfs = get_fs(); |
| 872 | set_fs(KERNEL_DS); | 872 | set_fs(KERNEL_DS); |
| 873 | host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); | 873 | host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset, 0); |
| 874 | set_fs(oldfs); | 874 | set_fs(oldfs); |
| 875 | return nfsd_finish_read(file, count, host_err); | 875 | return nfsd_finish_read(file, count, host_err); |
| 876 | } | 876 | } |
| @@ -957,7 +957,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 957 | 957 | ||
| 958 | /* Write the data. */ | 958 | /* Write the data. */ |
| 959 | oldfs = get_fs(); set_fs(KERNEL_DS); | 959 | oldfs = get_fs(); set_fs(KERNEL_DS); |
| 960 | host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos); | 960 | host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos, 0); |
| 961 | set_fs(oldfs); | 961 | set_fs(oldfs); |
| 962 | if (host_err < 0) | 962 | if (host_err < 0) |
| 963 | goto out_nfserr; | 963 | goto out_nfserr; |
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index 2256e7e23e67..3f1190d18991 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c | |||
| @@ -199,6 +199,8 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt) | |||
| 199 | if (sb->s_op->show_devname) { | 199 | if (sb->s_op->show_devname) { |
| 200 | seq_puts(m, "device "); | 200 | seq_puts(m, "device "); |
| 201 | err = sb->s_op->show_devname(m, mnt_path.dentry); | 201 | err = sb->s_op->show_devname(m, mnt_path.dentry); |
| 202 | if (err) | ||
| 203 | goto out; | ||
| 202 | } else { | 204 | } else { |
| 203 | if (r->mnt_devname) { | 205 | if (r->mnt_devname) { |
| 204 | seq_puts(m, "device "); | 206 | seq_puts(m, "device "); |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 3c3b81bb6dfe..04ca0cc6d065 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -2430,9 +2430,7 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name, | |||
| 2430 | struct dentry *dentry; | 2430 | struct dentry *dentry; |
| 2431 | int error; | 2431 | int error; |
| 2432 | 2432 | ||
| 2433 | inode_lock(d_inode(sb->s_root)); | 2433 | dentry = lookup_one_len_unlocked(qf_name, sb->s_root, strlen(qf_name)); |
| 2434 | dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name)); | ||
| 2435 | inode_unlock(d_inode(sb->s_root)); | ||
| 2436 | if (IS_ERR(dentry)) | 2434 | if (IS_ERR(dentry)) |
| 2437 | return PTR_ERR(dentry); | 2435 | return PTR_ERR(dentry); |
| 2438 | 2436 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index dadf24e5c95b..cf377cf9dfe3 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -693,12 +693,17 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) | |||
| 693 | EXPORT_SYMBOL(iov_shorten); | 693 | EXPORT_SYMBOL(iov_shorten); |
| 694 | 694 | ||
| 695 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | 695 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, |
| 696 | loff_t *ppos, iter_fn_t fn) | 696 | loff_t *ppos, iter_fn_t fn, int flags) |
| 697 | { | 697 | { |
| 698 | struct kiocb kiocb; | 698 | struct kiocb kiocb; |
| 699 | ssize_t ret; | 699 | ssize_t ret; |
| 700 | 700 | ||
| 701 | if (flags & ~RWF_HIPRI) | ||
| 702 | return -EOPNOTSUPP; | ||
| 703 | |||
| 701 | init_sync_kiocb(&kiocb, filp); | 704 | init_sync_kiocb(&kiocb, filp); |
| 705 | if (flags & RWF_HIPRI) | ||
| 706 | kiocb.ki_flags |= IOCB_HIPRI; | ||
| 702 | kiocb.ki_pos = *ppos; | 707 | kiocb.ki_pos = *ppos; |
| 703 | 708 | ||
| 704 | ret = fn(&kiocb, iter); | 709 | ret = fn(&kiocb, iter); |
| @@ -709,10 +714,13 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | |||
| 709 | 714 | ||
| 710 | /* Do it by hand, with file-ops */ | 715 | /* Do it by hand, with file-ops */ |
| 711 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, | 716 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, |
| 712 | loff_t *ppos, io_fn_t fn) | 717 | loff_t *ppos, io_fn_t fn, int flags) |
| 713 | { | 718 | { |
| 714 | ssize_t ret = 0; | 719 | ssize_t ret = 0; |
| 715 | 720 | ||
| 721 | if (flags & ~RWF_HIPRI) | ||
| 722 | return -EOPNOTSUPP; | ||
| 723 | |||
| 716 | while (iov_iter_count(iter)) { | 724 | while (iov_iter_count(iter)) { |
| 717 | struct iovec iovec = iov_iter_iovec(iter); | 725 | struct iovec iovec = iov_iter_iovec(iter); |
| 718 | ssize_t nr; | 726 | ssize_t nr; |
| @@ -813,7 +821,8 @@ out: | |||
| 813 | 821 | ||
| 814 | static ssize_t do_readv_writev(int type, struct file *file, | 822 | static ssize_t do_readv_writev(int type, struct file *file, |
| 815 | const struct iovec __user * uvector, | 823 | const struct iovec __user * uvector, |
| 816 | unsigned long nr_segs, loff_t *pos) | 824 | unsigned long nr_segs, loff_t *pos, |
| 825 | int flags) | ||
| 817 | { | 826 | { |
| 818 | size_t tot_len; | 827 | size_t tot_len; |
| 819 | struct iovec iovstack[UIO_FASTIOV]; | 828 | struct iovec iovstack[UIO_FASTIOV]; |
| @@ -845,9 +854,9 @@ static ssize_t do_readv_writev(int type, struct file *file, | |||
| 845 | } | 854 | } |
| 846 | 855 | ||
| 847 | if (iter_fn) | 856 | if (iter_fn) |
| 848 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn); | 857 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); |
| 849 | else | 858 | else |
| 850 | ret = do_loop_readv_writev(file, &iter, pos, fn); | 859 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); |
| 851 | 860 | ||
| 852 | if (type != READ) | 861 | if (type != READ) |
| 853 | file_end_write(file); | 862 | file_end_write(file); |
| @@ -864,40 +873,40 @@ out: | |||
| 864 | } | 873 | } |
| 865 | 874 | ||
| 866 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, | 875 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, |
| 867 | unsigned long vlen, loff_t *pos) | 876 | unsigned long vlen, loff_t *pos, int flags) |
| 868 | { | 877 | { |
| 869 | if (!(file->f_mode & FMODE_READ)) | 878 | if (!(file->f_mode & FMODE_READ)) |
| 870 | return -EBADF; | 879 | return -EBADF; |
| 871 | if (!(file->f_mode & FMODE_CAN_READ)) | 880 | if (!(file->f_mode & FMODE_CAN_READ)) |
| 872 | return -EINVAL; | 881 | return -EINVAL; |
| 873 | 882 | ||
| 874 | return do_readv_writev(READ, file, vec, vlen, pos); | 883 | return do_readv_writev(READ, file, vec, vlen, pos, flags); |
| 875 | } | 884 | } |
| 876 | 885 | ||
| 877 | EXPORT_SYMBOL(vfs_readv); | 886 | EXPORT_SYMBOL(vfs_readv); |
| 878 | 887 | ||
| 879 | ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, | 888 | ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, |
| 880 | unsigned long vlen, loff_t *pos) | 889 | unsigned long vlen, loff_t *pos, int flags) |
| 881 | { | 890 | { |
| 882 | if (!(file->f_mode & FMODE_WRITE)) | 891 | if (!(file->f_mode & FMODE_WRITE)) |
| 883 | return -EBADF; | 892 | return -EBADF; |
| 884 | if (!(file->f_mode & FMODE_CAN_WRITE)) | 893 | if (!(file->f_mode & FMODE_CAN_WRITE)) |
| 885 | return -EINVAL; | 894 | return -EINVAL; |
| 886 | 895 | ||
| 887 | return do_readv_writev(WRITE, file, vec, vlen, pos); | 896 | return do_readv_writev(WRITE, file, vec, vlen, pos, flags); |
| 888 | } | 897 | } |
| 889 | 898 | ||
| 890 | EXPORT_SYMBOL(vfs_writev); | 899 | EXPORT_SYMBOL(vfs_writev); |
| 891 | 900 | ||
| 892 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | 901 | static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec, |
| 893 | unsigned long, vlen) | 902 | unsigned long vlen, int flags) |
| 894 | { | 903 | { |
| 895 | struct fd f = fdget_pos(fd); | 904 | struct fd f = fdget_pos(fd); |
| 896 | ssize_t ret = -EBADF; | 905 | ssize_t ret = -EBADF; |
| 897 | 906 | ||
| 898 | if (f.file) { | 907 | if (f.file) { |
| 899 | loff_t pos = file_pos_read(f.file); | 908 | loff_t pos = file_pos_read(f.file); |
| 900 | ret = vfs_readv(f.file, vec, vlen, &pos); | 909 | ret = vfs_readv(f.file, vec, vlen, &pos, flags); |
| 901 | if (ret >= 0) | 910 | if (ret >= 0) |
| 902 | file_pos_write(f.file, pos); | 911 | file_pos_write(f.file, pos); |
| 903 | fdput_pos(f); | 912 | fdput_pos(f); |
| @@ -909,15 +918,15 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
| 909 | return ret; | 918 | return ret; |
| 910 | } | 919 | } |
| 911 | 920 | ||
| 912 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | 921 | static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec, |
| 913 | unsigned long, vlen) | 922 | unsigned long vlen, int flags) |
| 914 | { | 923 | { |
| 915 | struct fd f = fdget_pos(fd); | 924 | struct fd f = fdget_pos(fd); |
| 916 | ssize_t ret = -EBADF; | 925 | ssize_t ret = -EBADF; |
| 917 | 926 | ||
| 918 | if (f.file) { | 927 | if (f.file) { |
| 919 | loff_t pos = file_pos_read(f.file); | 928 | loff_t pos = file_pos_read(f.file); |
| 920 | ret = vfs_writev(f.file, vec, vlen, &pos); | 929 | ret = vfs_writev(f.file, vec, vlen, &pos, flags); |
| 921 | if (ret >= 0) | 930 | if (ret >= 0) |
| 922 | file_pos_write(f.file, pos); | 931 | file_pos_write(f.file, pos); |
| 923 | fdput_pos(f); | 932 | fdput_pos(f); |
| @@ -935,10 +944,9 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low) | |||
| 935 | return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low; | 944 | return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low; |
| 936 | } | 945 | } |
| 937 | 946 | ||
| 938 | SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | 947 | static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec, |
| 939 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | 948 | unsigned long vlen, loff_t pos, int flags) |
| 940 | { | 949 | { |
| 941 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 942 | struct fd f; | 950 | struct fd f; |
| 943 | ssize_t ret = -EBADF; | 951 | ssize_t ret = -EBADF; |
| 944 | 952 | ||
| @@ -949,7 +957,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | |||
| 949 | if (f.file) { | 957 | if (f.file) { |
| 950 | ret = -ESPIPE; | 958 | ret = -ESPIPE; |
| 951 | if (f.file->f_mode & FMODE_PREAD) | 959 | if (f.file->f_mode & FMODE_PREAD) |
| 952 | ret = vfs_readv(f.file, vec, vlen, &pos); | 960 | ret = vfs_readv(f.file, vec, vlen, &pos, flags); |
| 953 | fdput(f); | 961 | fdput(f); |
| 954 | } | 962 | } |
| 955 | 963 | ||
| @@ -959,10 +967,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | |||
| 959 | return ret; | 967 | return ret; |
| 960 | } | 968 | } |
| 961 | 969 | ||
| 962 | SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | 970 | static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec, |
| 963 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | 971 | unsigned long vlen, loff_t pos, int flags) |
| 964 | { | 972 | { |
| 965 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 966 | struct fd f; | 973 | struct fd f; |
| 967 | ssize_t ret = -EBADF; | 974 | ssize_t ret = -EBADF; |
| 968 | 975 | ||
| @@ -973,7 +980,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
| 973 | if (f.file) { | 980 | if (f.file) { |
| 974 | ret = -ESPIPE; | 981 | ret = -ESPIPE; |
| 975 | if (f.file->f_mode & FMODE_PWRITE) | 982 | if (f.file->f_mode & FMODE_PWRITE) |
| 976 | ret = vfs_writev(f.file, vec, vlen, &pos); | 983 | ret = vfs_writev(f.file, vec, vlen, &pos, flags); |
| 977 | fdput(f); | 984 | fdput(f); |
| 978 | } | 985 | } |
| 979 | 986 | ||
| @@ -983,11 +990,64 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
| 983 | return ret; | 990 | return ret; |
| 984 | } | 991 | } |
| 985 | 992 | ||
| 993 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | ||
| 994 | unsigned long, vlen) | ||
| 995 | { | ||
| 996 | return do_readv(fd, vec, vlen, 0); | ||
| 997 | } | ||
| 998 | |||
| 999 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | ||
| 1000 | unsigned long, vlen) | ||
| 1001 | { | ||
| 1002 | return do_writev(fd, vec, vlen, 0); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | ||
| 1006 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | ||
| 1007 | { | ||
| 1008 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 1009 | |||
| 1010 | return do_preadv(fd, vec, vlen, pos, 0); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec, | ||
| 1014 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h, | ||
| 1015 | int, flags) | ||
| 1016 | { | ||
| 1017 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 1018 | |||
| 1019 | if (pos == -1) | ||
| 1020 | return do_readv(fd, vec, vlen, flags); | ||
| 1021 | |||
| 1022 | return do_preadv(fd, vec, vlen, pos, flags); | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | ||
| 1026 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) | ||
| 1027 | { | ||
| 1028 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 1029 | |||
| 1030 | return do_pwritev(fd, vec, vlen, pos, 0); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec, | ||
| 1034 | unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h, | ||
| 1035 | int, flags) | ||
| 1036 | { | ||
| 1037 | loff_t pos = pos_from_hilo(pos_h, pos_l); | ||
| 1038 | |||
| 1039 | if (pos == -1) | ||
| 1040 | return do_writev(fd, vec, vlen, flags); | ||
| 1041 | |||
| 1042 | return do_pwritev(fd, vec, vlen, pos, flags); | ||
| 1043 | } | ||
| 1044 | |||
| 986 | #ifdef CONFIG_COMPAT | 1045 | #ifdef CONFIG_COMPAT |
| 987 | 1046 | ||
| 988 | static ssize_t compat_do_readv_writev(int type, struct file *file, | 1047 | static ssize_t compat_do_readv_writev(int type, struct file *file, |
| 989 | const struct compat_iovec __user *uvector, | 1048 | const struct compat_iovec __user *uvector, |
| 990 | unsigned long nr_segs, loff_t *pos) | 1049 | unsigned long nr_segs, loff_t *pos, |
| 1050 | int flags) | ||
| 991 | { | 1051 | { |
| 992 | compat_ssize_t tot_len; | 1052 | compat_ssize_t tot_len; |
| 993 | struct iovec iovstack[UIO_FASTIOV]; | 1053 | struct iovec iovstack[UIO_FASTIOV]; |
| @@ -1019,9 +1079,9 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
| 1019 | } | 1079 | } |
| 1020 | 1080 | ||
| 1021 | if (iter_fn) | 1081 | if (iter_fn) |
| 1022 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn); | 1082 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); |
| 1023 | else | 1083 | else |
| 1024 | ret = do_loop_readv_writev(file, &iter, pos, fn); | 1084 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); |
| 1025 | 1085 | ||
| 1026 | if (type != READ) | 1086 | if (type != READ) |
| 1027 | file_end_write(file); | 1087 | file_end_write(file); |
| @@ -1039,7 +1099,7 @@ out: | |||
| 1039 | 1099 | ||
| 1040 | static size_t compat_readv(struct file *file, | 1100 | static size_t compat_readv(struct file *file, |
| 1041 | const struct compat_iovec __user *vec, | 1101 | const struct compat_iovec __user *vec, |
| 1042 | unsigned long vlen, loff_t *pos) | 1102 | unsigned long vlen, loff_t *pos, int flags) |
| 1043 | { | 1103 | { |
| 1044 | ssize_t ret = -EBADF; | 1104 | ssize_t ret = -EBADF; |
| 1045 | 1105 | ||
| @@ -1050,7 +1110,7 @@ static size_t compat_readv(struct file *file, | |||
| 1050 | if (!(file->f_mode & FMODE_CAN_READ)) | 1110 | if (!(file->f_mode & FMODE_CAN_READ)) |
| 1051 | goto out; | 1111 | goto out; |
| 1052 | 1112 | ||
| 1053 | ret = compat_do_readv_writev(READ, file, vec, vlen, pos); | 1113 | ret = compat_do_readv_writev(READ, file, vec, vlen, pos, flags); |
| 1054 | 1114 | ||
| 1055 | out: | 1115 | out: |
| 1056 | if (ret > 0) | 1116 | if (ret > 0) |
| @@ -1059,9 +1119,9 @@ out: | |||
| 1059 | return ret; | 1119 | return ret; |
| 1060 | } | 1120 | } |
| 1061 | 1121 | ||
| 1062 | COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | 1122 | static size_t do_compat_readv(compat_ulong_t fd, |
| 1063 | const struct compat_iovec __user *,vec, | 1123 | const struct compat_iovec __user *vec, |
| 1064 | compat_ulong_t, vlen) | 1124 | compat_ulong_t vlen, int flags) |
| 1065 | { | 1125 | { |
| 1066 | struct fd f = fdget_pos(fd); | 1126 | struct fd f = fdget_pos(fd); |
| 1067 | ssize_t ret; | 1127 | ssize_t ret; |
| @@ -1070,16 +1130,24 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | |||
| 1070 | if (!f.file) | 1130 | if (!f.file) |
| 1071 | return -EBADF; | 1131 | return -EBADF; |
| 1072 | pos = f.file->f_pos; | 1132 | pos = f.file->f_pos; |
| 1073 | ret = compat_readv(f.file, vec, vlen, &pos); | 1133 | ret = compat_readv(f.file, vec, vlen, &pos, flags); |
| 1074 | if (ret >= 0) | 1134 | if (ret >= 0) |
| 1075 | f.file->f_pos = pos; | 1135 | f.file->f_pos = pos; |
| 1076 | fdput_pos(f); | 1136 | fdput_pos(f); |
| 1077 | return ret; | 1137 | return ret; |
| 1138 | |||
| 1139 | } | ||
| 1140 | |||
| 1141 | COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | ||
| 1142 | const struct compat_iovec __user *,vec, | ||
| 1143 | compat_ulong_t, vlen) | ||
| 1144 | { | ||
| 1145 | return do_compat_readv(fd, vec, vlen, 0); | ||
| 1078 | } | 1146 | } |
| 1079 | 1147 | ||
| 1080 | static long __compat_sys_preadv64(unsigned long fd, | 1148 | static long do_compat_preadv64(unsigned long fd, |
| 1081 | const struct compat_iovec __user *vec, | 1149 | const struct compat_iovec __user *vec, |
| 1082 | unsigned long vlen, loff_t pos) | 1150 | unsigned long vlen, loff_t pos, int flags) |
| 1083 | { | 1151 | { |
| 1084 | struct fd f; | 1152 | struct fd f; |
| 1085 | ssize_t ret; | 1153 | ssize_t ret; |
| @@ -1091,7 +1159,7 @@ static long __compat_sys_preadv64(unsigned long fd, | |||
| 1091 | return -EBADF; | 1159 | return -EBADF; |
| 1092 | ret = -ESPIPE; | 1160 | ret = -ESPIPE; |
| 1093 | if (f.file->f_mode & FMODE_PREAD) | 1161 | if (f.file->f_mode & FMODE_PREAD) |
| 1094 | ret = compat_readv(f.file, vec, vlen, &pos); | 1162 | ret = compat_readv(f.file, vec, vlen, &pos, flags); |
| 1095 | fdput(f); | 1163 | fdput(f); |
| 1096 | return ret; | 1164 | return ret; |
| 1097 | } | 1165 | } |
| @@ -1101,7 +1169,7 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, | |||
| 1101 | const struct compat_iovec __user *,vec, | 1169 | const struct compat_iovec __user *,vec, |
| 1102 | unsigned long, vlen, loff_t, pos) | 1170 | unsigned long, vlen, loff_t, pos) |
| 1103 | { | 1171 | { |
| 1104 | return __compat_sys_preadv64(fd, vec, vlen, pos); | 1172 | return do_compat_preadv64(fd, vec, vlen, pos, 0); |
| 1105 | } | 1173 | } |
| 1106 | #endif | 1174 | #endif |
| 1107 | 1175 | ||
| @@ -1111,12 +1179,25 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, | |||
| 1111 | { | 1179 | { |
| 1112 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | 1180 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; |
| 1113 | 1181 | ||
| 1114 | return __compat_sys_preadv64(fd, vec, vlen, pos); | 1182 | return do_compat_preadv64(fd, vec, vlen, pos, 0); |
| 1183 | } | ||
| 1184 | |||
| 1185 | COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd, | ||
| 1186 | const struct compat_iovec __user *,vec, | ||
| 1187 | compat_ulong_t, vlen, u32, pos_low, u32, pos_high, | ||
| 1188 | int, flags) | ||
| 1189 | { | ||
| 1190 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | ||
| 1191 | |||
| 1192 | if (pos == -1) | ||
| 1193 | return do_compat_readv(fd, vec, vlen, flags); | ||
| 1194 | |||
| 1195 | return do_compat_preadv64(fd, vec, vlen, pos, flags); | ||
| 1115 | } | 1196 | } |
| 1116 | 1197 | ||
| 1117 | static size_t compat_writev(struct file *file, | 1198 | static size_t compat_writev(struct file *file, |
| 1118 | const struct compat_iovec __user *vec, | 1199 | const struct compat_iovec __user *vec, |
| 1119 | unsigned long vlen, loff_t *pos) | 1200 | unsigned long vlen, loff_t *pos, int flags) |
| 1120 | { | 1201 | { |
| 1121 | ssize_t ret = -EBADF; | 1202 | ssize_t ret = -EBADF; |
| 1122 | 1203 | ||
| @@ -1127,7 +1208,7 @@ static size_t compat_writev(struct file *file, | |||
| 1127 | if (!(file->f_mode & FMODE_CAN_WRITE)) | 1208 | if (!(file->f_mode & FMODE_CAN_WRITE)) |
| 1128 | goto out; | 1209 | goto out; |
| 1129 | 1210 | ||
| 1130 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); | 1211 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, 0); |
| 1131 | 1212 | ||
| 1132 | out: | 1213 | out: |
| 1133 | if (ret > 0) | 1214 | if (ret > 0) |
| @@ -1136,9 +1217,9 @@ out: | |||
| 1136 | return ret; | 1217 | return ret; |
| 1137 | } | 1218 | } |
| 1138 | 1219 | ||
| 1139 | COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, | 1220 | static size_t do_compat_writev(compat_ulong_t fd, |
| 1140 | const struct compat_iovec __user *, vec, | 1221 | const struct compat_iovec __user* vec, |
| 1141 | compat_ulong_t, vlen) | 1222 | compat_ulong_t vlen, int flags) |
| 1142 | { | 1223 | { |
| 1143 | struct fd f = fdget_pos(fd); | 1224 | struct fd f = fdget_pos(fd); |
| 1144 | ssize_t ret; | 1225 | ssize_t ret; |
| @@ -1147,16 +1228,23 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, | |||
| 1147 | if (!f.file) | 1228 | if (!f.file) |
| 1148 | return -EBADF; | 1229 | return -EBADF; |
| 1149 | pos = f.file->f_pos; | 1230 | pos = f.file->f_pos; |
| 1150 | ret = compat_writev(f.file, vec, vlen, &pos); | 1231 | ret = compat_writev(f.file, vec, vlen, &pos, flags); |
| 1151 | if (ret >= 0) | 1232 | if (ret >= 0) |
| 1152 | f.file->f_pos = pos; | 1233 | f.file->f_pos = pos; |
| 1153 | fdput_pos(f); | 1234 | fdput_pos(f); |
| 1154 | return ret; | 1235 | return ret; |
| 1155 | } | 1236 | } |
| 1156 | 1237 | ||
| 1157 | static long __compat_sys_pwritev64(unsigned long fd, | 1238 | COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, |
| 1239 | const struct compat_iovec __user *, vec, | ||
| 1240 | compat_ulong_t, vlen) | ||
| 1241 | { | ||
| 1242 | return do_compat_writev(fd, vec, vlen, 0); | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | static long do_compat_pwritev64(unsigned long fd, | ||
| 1158 | const struct compat_iovec __user *vec, | 1246 | const struct compat_iovec __user *vec, |
| 1159 | unsigned long vlen, loff_t pos) | 1247 | unsigned long vlen, loff_t pos, int flags) |
| 1160 | { | 1248 | { |
| 1161 | struct fd f; | 1249 | struct fd f; |
| 1162 | ssize_t ret; | 1250 | ssize_t ret; |
| @@ -1168,7 +1256,7 @@ static long __compat_sys_pwritev64(unsigned long fd, | |||
| 1168 | return -EBADF; | 1256 | return -EBADF; |
| 1169 | ret = -ESPIPE; | 1257 | ret = -ESPIPE; |
| 1170 | if (f.file->f_mode & FMODE_PWRITE) | 1258 | if (f.file->f_mode & FMODE_PWRITE) |
| 1171 | ret = compat_writev(f.file, vec, vlen, &pos); | 1259 | ret = compat_writev(f.file, vec, vlen, &pos, flags); |
| 1172 | fdput(f); | 1260 | fdput(f); |
| 1173 | return ret; | 1261 | return ret; |
| 1174 | } | 1262 | } |
| @@ -1178,7 +1266,7 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, | |||
| 1178 | const struct compat_iovec __user *,vec, | 1266 | const struct compat_iovec __user *,vec, |
| 1179 | unsigned long, vlen, loff_t, pos) | 1267 | unsigned long, vlen, loff_t, pos) |
| 1180 | { | 1268 | { |
| 1181 | return __compat_sys_pwritev64(fd, vec, vlen, pos); | 1269 | return do_compat_pwritev64(fd, vec, vlen, pos, 0); |
| 1182 | } | 1270 | } |
| 1183 | #endif | 1271 | #endif |
| 1184 | 1272 | ||
| @@ -1188,8 +1276,21 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, | |||
| 1188 | { | 1276 | { |
| 1189 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | 1277 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; |
| 1190 | 1278 | ||
| 1191 | return __compat_sys_pwritev64(fd, vec, vlen, pos); | 1279 | return do_compat_pwritev64(fd, vec, vlen, pos, 0); |
| 1280 | } | ||
| 1281 | |||
| 1282 | COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd, | ||
| 1283 | const struct compat_iovec __user *,vec, | ||
| 1284 | compat_ulong_t, vlen, u32, pos_low, u32, pos_high, int, flags) | ||
| 1285 | { | ||
| 1286 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | ||
| 1287 | |||
| 1288 | if (pos == -1) | ||
| 1289 | return do_compat_writev(fd, vec, vlen, flags); | ||
| 1290 | |||
| 1291 | return do_compat_pwritev64(fd, vec, vlen, pos, flags); | ||
| 1192 | } | 1292 | } |
| 1293 | |||
| 1193 | #endif | 1294 | #endif |
| 1194 | 1295 | ||
| 1195 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | 1296 | static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, |
diff --git a/fs/splice.c b/fs/splice.c index 82bc0d64fc38..9947b5c69664 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -185,6 +185,9 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
| 185 | unsigned int spd_pages = spd->nr_pages; | 185 | unsigned int spd_pages = spd->nr_pages; |
| 186 | int ret, do_wakeup, page_nr; | 186 | int ret, do_wakeup, page_nr; |
| 187 | 187 | ||
| 188 | if (!spd_pages) | ||
| 189 | return 0; | ||
| 190 | |||
| 188 | ret = 0; | 191 | ret = 0; |
| 189 | do_wakeup = 0; | 192 | do_wakeup = 0; |
| 190 | page_nr = 0; | 193 | page_nr = 0; |
| @@ -577,7 +580,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec, | |||
| 577 | old_fs = get_fs(); | 580 | old_fs = get_fs(); |
| 578 | set_fs(get_ds()); | 581 | set_fs(get_ds()); |
| 579 | /* The cast to a user pointer is valid due to the set_fs() */ | 582 | /* The cast to a user pointer is valid due to the set_fs() */ |
| 580 | res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos); | 583 | res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos, 0); |
| 581 | set_fs(old_fs); | 584 | set_fs(old_fs); |
| 582 | 585 | ||
| 583 | return res; | 586 | return res; |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4571ef1a12a9..458f6efe3a21 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -499,7 +499,8 @@ struct request_queue { | |||
| 499 | 499 | ||
| 500 | #define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 500 | #define QUEUE_FLAG_MQ_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
| 501 | (1 << QUEUE_FLAG_STACKABLE) | \ | 501 | (1 << QUEUE_FLAG_STACKABLE) | \ |
| 502 | (1 << QUEUE_FLAG_SAME_COMP)) | 502 | (1 << QUEUE_FLAG_SAME_COMP) | \ |
| 503 | (1 << QUEUE_FLAG_POLL)) | ||
| 503 | 504 | ||
| 504 | static inline void queue_lockdep_assert_held(struct request_queue *q) | 505 | static inline void queue_lockdep_assert_held(struct request_queue *q) |
| 505 | { | 506 | { |
diff --git a/include/linux/compat.h b/include/linux/compat.h index a76c9172b2eb..fe4ccd0c748a 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
| @@ -340,6 +340,12 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, | |||
| 340 | asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, | 340 | asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, |
| 341 | const struct compat_iovec __user *vec, | 341 | const struct compat_iovec __user *vec, |
| 342 | compat_ulong_t vlen, u32 pos_low, u32 pos_high); | 342 | compat_ulong_t vlen, u32 pos_low, u32 pos_high); |
| 343 | asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd, | ||
| 344 | const struct compat_iovec __user *vec, | ||
| 345 | compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags); | ||
| 346 | asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd, | ||
| 347 | const struct compat_iovec __user *vec, | ||
| 348 | compat_ulong_t vlen, u32 pos_low, u32 pos_high, int flags); | ||
| 343 | 349 | ||
| 344 | #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 | 350 | #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 |
| 345 | asmlinkage long compat_sys_preadv64(unsigned long fd, | 351 | asmlinkage long compat_sys_preadv64(unsigned long fd, |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index c4b5f4b3f8f8..1c51d2d84a32 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
| @@ -246,6 +246,7 @@ extern struct dentry * d_alloc(struct dentry *, const struct qstr *); | |||
| 246 | extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); | 246 | extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); |
| 247 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); | 247 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); |
| 248 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); | 248 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); |
| 249 | extern struct dentry * d_exact_alias(struct dentry *, struct inode *); | ||
| 249 | extern struct dentry *d_find_any_alias(struct inode *inode); | 250 | extern struct dentry *d_find_any_alias(struct inode *inode); |
| 250 | extern struct dentry * d_obtain_alias(struct inode *); | 251 | extern struct dentry * d_obtain_alias(struct inode *); |
| 251 | extern struct dentry * d_obtain_root(struct inode *); | 252 | extern struct dentry * d_obtain_root(struct inode *); |
| @@ -272,38 +273,8 @@ extern int have_submounts(struct dentry *); | |||
| 272 | * This adds the entry to the hash queues. | 273 | * This adds the entry to the hash queues. |
| 273 | */ | 274 | */ |
| 274 | extern void d_rehash(struct dentry *); | 275 | extern void d_rehash(struct dentry *); |
| 275 | |||
| 276 | /** | ||
| 277 | * d_add - add dentry to hash queues | ||
| 278 | * @entry: dentry to add | ||
| 279 | * @inode: The inode to attach to this dentry | ||
| 280 | * | ||
| 281 | * This adds the entry to the hash queues and initializes @inode. | ||
| 282 | * The entry was actually filled in earlier during d_alloc(). | ||
| 283 | */ | ||
| 284 | 276 | ||
| 285 | static inline void d_add(struct dentry *entry, struct inode *inode) | 277 | extern void d_add(struct dentry *, struct inode *); |
| 286 | { | ||
| 287 | d_instantiate(entry, inode); | ||
| 288 | d_rehash(entry); | ||
| 289 | } | ||
| 290 | |||
| 291 | /** | ||
| 292 | * d_add_unique - add dentry to hash queues without aliasing | ||
| 293 | * @entry: dentry to add | ||
| 294 | * @inode: The inode to attach to this dentry | ||
| 295 | * | ||
| 296 | * This adds the entry to the hash queues and initializes @inode. | ||
| 297 | * The entry was actually filled in earlier during d_alloc(). | ||
| 298 | */ | ||
| 299 | static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *inode) | ||
| 300 | { | ||
| 301 | struct dentry *res; | ||
| 302 | |||
| 303 | res = d_instantiate_unique(entry, inode); | ||
| 304 | d_rehash(res != NULL ? res : entry); | ||
| 305 | return res; | ||
| 306 | } | ||
| 307 | 278 | ||
| 308 | extern void dentry_update_name_case(struct dentry *, struct qstr *); | 279 | extern void dentry_update_name_case(struct dentry *, struct qstr *); |
| 309 | 280 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index ae681002100a..3a0d6e54208d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -320,6 +320,7 @@ struct writeback_control; | |||
| 320 | #define IOCB_EVENTFD (1 << 0) | 320 | #define IOCB_EVENTFD (1 << 0) |
| 321 | #define IOCB_APPEND (1 << 1) | 321 | #define IOCB_APPEND (1 << 1) |
| 322 | #define IOCB_DIRECT (1 << 2) | 322 | #define IOCB_DIRECT (1 << 2) |
| 323 | #define IOCB_HIPRI (1 << 3) | ||
| 323 | 324 | ||
| 324 | struct kiocb { | 325 | struct kiocb { |
| 325 | struct file *ki_filp; | 326 | struct file *ki_filp; |
| @@ -1540,11 +1541,6 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de | |||
| 1540 | extern int vfs_whiteout(struct inode *, struct dentry *); | 1541 | extern int vfs_whiteout(struct inode *, struct dentry *); |
| 1541 | 1542 | ||
| 1542 | /* | 1543 | /* |
| 1543 | * VFS dentry helper functions. | ||
| 1544 | */ | ||
| 1545 | extern void dentry_unhash(struct dentry *dentry); | ||
| 1546 | |||
| 1547 | /* | ||
| 1548 | * VFS file helper functions. | 1544 | * VFS file helper functions. |
| 1549 | */ | 1545 | */ |
| 1550 | extern void inode_init_owner(struct inode *inode, const struct inode *dir, | 1546 | extern void inode_init_owner(struct inode *inode, const struct inode *dir, |
| @@ -1709,9 +1705,9 @@ extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *) | |||
| 1709 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); | 1705 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); |
| 1710 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); | 1706 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); |
| 1711 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, | 1707 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, |
| 1712 | unsigned long, loff_t *); | 1708 | unsigned long, loff_t *, int); |
| 1713 | extern ssize_t vfs_writev(struct file *, const struct iovec __user *, | 1709 | extern ssize_t vfs_writev(struct file *, const struct iovec __user *, |
| 1714 | unsigned long, loff_t *); | 1710 | unsigned long, loff_t *, int); |
| 1715 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, | 1711 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, |
| 1716 | loff_t, size_t, unsigned int); | 1712 | loff_t, size_t, unsigned int); |
| 1717 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, | 1713 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 7ee1774edee5..0141f257d67b 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
| @@ -16,15 +16,6 @@ | |||
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/bug.h> | 17 | #include <linux/bug.h> |
| 18 | 18 | ||
| 19 | /* | ||
| 20 | * fsnotify_d_instantiate - instantiate a dentry for inode | ||
| 21 | */ | ||
| 22 | static inline void fsnotify_d_instantiate(struct dentry *dentry, | ||
| 23 | struct inode *inode) | ||
| 24 | { | ||
| 25 | __fsnotify_d_instantiate(dentry, inode); | ||
| 26 | } | ||
| 27 | |||
| 28 | /* Notify this dentry's parent about a child's events. */ | 19 | /* Notify this dentry's parent about a child's events. */ |
| 29 | static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) | 20 | static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) |
| 30 | { | 21 | { |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 6b7e89f45aa4..827b249259f7 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -293,14 +293,9 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) | |||
| 293 | /* | 293 | /* |
| 294 | * fsnotify_d_instantiate - instantiate a dentry for inode | 294 | * fsnotify_d_instantiate - instantiate a dentry for inode |
| 295 | */ | 295 | */ |
| 296 | static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode) | 296 | static inline void __fsnotify_d_instantiate(struct dentry *dentry) |
| 297 | { | 297 | { |
| 298 | if (!inode) | ||
| 299 | return; | ||
| 300 | |||
| 301 | spin_lock(&dentry->d_lock); | ||
| 302 | __fsnotify_update_dcache_flags(dentry); | 298 | __fsnotify_update_dcache_flags(dentry); |
| 303 | spin_unlock(&dentry->d_lock); | ||
| 304 | } | 299 | } |
| 305 | 300 | ||
| 306 | /* called from fsnotify listeners, such as fanotify or dnotify */ | 301 | /* called from fsnotify listeners, such as fanotify or dnotify */ |
| @@ -399,7 +394,7 @@ static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) | |||
| 399 | static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) | 394 | static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) |
| 400 | {} | 395 | {} |
| 401 | 396 | ||
| 402 | static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode) | 397 | static inline void __fsnotify_d_instantiate(struct dentry *dentry) |
| 403 | {} | 398 | {} |
| 404 | 399 | ||
| 405 | static inline u32 fsnotify_get_cookie(void) | 400 | static inline u32 fsnotify_get_cookie(void) |
diff --git a/include/linux/namei.h b/include/linux/namei.h index d0f25d81b46a..77d01700daf7 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
| @@ -31,6 +31,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; | |||
| 31 | #define LOOKUP_PARENT 0x0010 | 31 | #define LOOKUP_PARENT 0x0010 |
| 32 | #define LOOKUP_REVAL 0x0020 | 32 | #define LOOKUP_REVAL 0x0020 |
| 33 | #define LOOKUP_RCU 0x0040 | 33 | #define LOOKUP_RCU 0x0040 |
| 34 | #define LOOKUP_NO_REVAL 0x0080 | ||
| 34 | 35 | ||
| 35 | /* | 36 | /* |
| 36 | * Intent data | 37 | * Intent data |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 185815c96433..d795472c54d8 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -575,8 +575,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, | |||
| 575 | size_t count, loff_t pos); | 575 | size_t count, loff_t pos); |
| 576 | asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, | 576 | asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, |
| 577 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); | 577 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); |
| 578 | asmlinkage long sys_preadv2(unsigned long fd, const struct iovec __user *vec, | ||
| 579 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h, | ||
| 580 | int flags); | ||
| 578 | asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, | 581 | asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, |
| 579 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); | 582 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); |
| 583 | asmlinkage long sys_pwritev2(unsigned long fd, const struct iovec __user *vec, | ||
| 584 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h, | ||
| 585 | int flags); | ||
| 580 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size); | 586 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size); |
| 581 | asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode); | 587 | asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode); |
| 582 | asmlinkage long sys_chdir(const char __user *filename); | 588 | asmlinkage long sys_chdir(const char __user *filename); |
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 149bec83a907..d2463396125c 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h | |||
| @@ -304,4 +304,7 @@ struct fsxattr { | |||
| 304 | #define SYNC_FILE_RANGE_WRITE 2 | 304 | #define SYNC_FILE_RANGE_WRITE 2 |
| 305 | #define SYNC_FILE_RANGE_WAIT_AFTER 4 | 305 | #define SYNC_FILE_RANGE_WAIT_AFTER 4 |
| 306 | 306 | ||
| 307 | /* flags for preadv2/pwritev2: */ | ||
| 308 | #define RWF_HIPRI 0x00000001 /* high priority request, poll if possible */ | ||
| 309 | |||
| 307 | #endif /* _UAPI_LINUX_FS_H */ | 310 | #endif /* _UAPI_LINUX_FS_H */ |
