Skip to content

Commit 1b8e949

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: xfs: Fix build breakage in xfs_iops.c when CONFIG_FS_POSIX_ACL is not set VFS: Reorganise shrink_dcache_for_umount_subtree() after demise of dcache_lock VFS: Remove dentry->d_lock locking from shrink_dcache_for_umount_subtree() VFS: Remove detached-dentry counter from shrink_dcache_for_umount_subtree() switch posix_acl_chmod() to umode_t switch posix_acl_from_mode() to umode_t switch posix_acl_equiv_mode() to umode_t * switch posix_acl_create() to umode_t * block: initialise bd_super in bdget() vfs: avoid call to inode_lru_list_del() if possible vfs: avoid taking inode_hash_lock on pipes and sockets vfs: conditionally call inode_wb_list_del() VFS: Fix automount for negative autofs dentries Btrfs: load the key from the dir item in readdir into a fake dentry devtmpfs: missing initialialization in never-hit case hppfs: missing include
2 parents 12ff47e + 206d440 commit 1b8e949

31 files changed

+161
-150
lines changed

drivers/base/devtmpfs.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static int create_path(const char *nodepath)
166166
{
167167
char *path;
168168
char *s;
169-
int err;
169+
int err = 0;
170170

171171
/* parent directories do not exist, create them */
172172
path = kstrdup(nodepath, GFP_KERNEL);

fs/9p/acl.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ int v9fs_set_create_acl(struct dentry *dentry,
182182
return 0;
183183
}
184184

185-
int v9fs_acl_mode(struct inode *dir, mode_t *modep,
185+
int v9fs_acl_mode(struct inode *dir, umode_t *modep,
186186
struct posix_acl **dpacl, struct posix_acl **pacl)
187187
{
188188
int retval = 0;
189-
mode_t mode = *modep;
189+
umode_t mode = *modep;
190190
struct posix_acl *acl = NULL;
191191

192192
if (!S_ISLNK(mode)) {
@@ -319,7 +319,7 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
319319
case ACL_TYPE_ACCESS:
320320
name = POSIX_ACL_XATTR_ACCESS;
321321
if (acl) {
322-
mode_t mode = inode->i_mode;
322+
umode_t mode = inode->i_mode;
323323
retval = posix_acl_equiv_mode(acl, &mode);
324324
if (retval < 0)
325325
goto err_out;

fs/9p/acl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
2020
extern int v9fs_acl_chmod(struct dentry *);
2121
extern int v9fs_set_create_acl(struct dentry *,
2222
struct posix_acl **, struct posix_acl **);
23-
extern int v9fs_acl_mode(struct inode *dir, mode_t *modep,
23+
extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
2424
struct posix_acl **dpacl, struct posix_acl **pacl);
2525
#else
2626
#define v9fs_iop_get_acl NULL
@@ -38,7 +38,7 @@ static inline int v9fs_set_create_acl(struct dentry *dentry,
3838
{
3939
return 0;
4040
}
41-
static inline int v9fs_acl_mode(struct inode *dir, mode_t *modep,
41+
static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep,
4242
struct posix_acl **dpacl,
4343
struct posix_acl **pacl)
4444
{

fs/9p/vfs_inode_dotl.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
206206
int err = 0;
207207
gid_t gid;
208208
int flags;
209-
mode_t mode;
209+
umode_t mode;
210210
char *name = NULL;
211211
struct file *filp;
212212
struct p9_qid qid;
@@ -348,7 +348,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
348348
struct p9_fid *fid = NULL, *dfid = NULL;
349349
gid_t gid;
350350
char *name;
351-
mode_t mode;
351+
umode_t mode;
352352
struct inode *inode;
353353
struct p9_qid qid;
354354
struct dentry *dir_dentry;
@@ -751,7 +751,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
751751
int err;
752752
gid_t gid;
753753
char *name;
754-
mode_t mode;
754+
umode_t mode;
755755
struct v9fs_session_info *v9ses;
756756
struct p9_fid *fid = NULL, *dfid = NULL;
757757
struct inode *inode;

fs/block_dev.c

+1
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ struct block_device *bdget(dev_t dev)
552552

553553
if (inode->i_state & I_NEW) {
554554
bdev->bd_contains = NULL;
555+
bdev->bd_super = NULL;
555556
bdev->bd_inode = inode;
556557
bdev->bd_block_size = (1 << inode->i_blkbits);
557558
bdev->bd_part_count = 0;

fs/btrfs/acl.c

+2-8
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
111111
int ret, size = 0;
112112
const char *name;
113113
char *value = NULL;
114-
mode_t mode;
115114

116115
if (acl) {
117116
ret = posix_acl_valid(acl);
@@ -122,13 +121,11 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
122121

123122
switch (type) {
124123
case ACL_TYPE_ACCESS:
125-
mode = inode->i_mode;
126124
name = POSIX_ACL_XATTR_ACCESS;
127125
if (acl) {
128-
ret = posix_acl_equiv_mode(acl, &mode);
126+
ret = posix_acl_equiv_mode(acl, &inode->i_mode);
129127
if (ret < 0)
130128
return ret;
131-
inode->i_mode = mode;
132129
}
133130
ret = 0;
134131
break;
@@ -222,19 +219,16 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans,
222219
}
223220

224221
if (IS_POSIXACL(dir) && acl) {
225-
mode_t mode = inode->i_mode;
226-
227222
if (S_ISDIR(inode->i_mode)) {
228223
ret = btrfs_set_acl(trans, inode, acl,
229224
ACL_TYPE_DEFAULT);
230225
if (ret)
231226
goto failed;
232227
}
233-
ret = posix_acl_create(&acl, GFP_NOFS, &mode);
228+
ret = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
234229
if (ret < 0)
235230
return ret;
236231

237-
inode->i_mode = mode;
238232
if (ret > 0) {
239233
/* we need an acl */
240234
ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS);

fs/btrfs/inode.c

+45-2
Original file line numberDiff line numberDiff line change
@@ -3993,12 +3993,19 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
39933993
struct btrfs_root *sub_root = root;
39943994
struct btrfs_key location;
39953995
int index;
3996-
int ret;
3996+
int ret = 0;
39973997

39983998
if (dentry->d_name.len > BTRFS_NAME_LEN)
39993999
return ERR_PTR(-ENAMETOOLONG);
40004000

4001-
ret = btrfs_inode_by_name(dir, dentry, &location);
4001+
if (unlikely(d_need_lookup(dentry))) {
4002+
memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));
4003+
kfree(dentry->d_fsdata);
4004+
dentry->d_fsdata = NULL;
4005+
d_clear_need_lookup(dentry);
4006+
} else {
4007+
ret = btrfs_inode_by_name(dir, dentry, &location);
4008+
}
40024009

40034010
if (ret < 0)
40044011
return ERR_PTR(ret);
@@ -4053,6 +4060,12 @@ static int btrfs_dentry_delete(const struct dentry *dentry)
40534060
return 0;
40544061
}
40554062

4063+
static void btrfs_dentry_release(struct dentry *dentry)
4064+
{
4065+
if (dentry->d_fsdata)
4066+
kfree(dentry->d_fsdata);
4067+
}
4068+
40564069
static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
40574070
struct nameidata *nd)
40584071
{
@@ -4075,6 +4088,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
40754088
struct btrfs_path *path;
40764089
struct list_head ins_list;
40774090
struct list_head del_list;
4091+
struct qstr q;
40784092
int ret;
40794093
struct extent_buffer *leaf;
40804094
int slot;
@@ -4164,6 +4178,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
41644178

41654179
while (di_cur < di_total) {
41664180
struct btrfs_key location;
4181+
struct dentry *tmp;
41674182

41684183
if (verify_dir_item(root, leaf, di))
41694184
break;
@@ -4184,6 +4199,33 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
41844199
d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
41854200
btrfs_dir_item_key_to_cpu(leaf, di, &location);
41864201

4202+
q.name = name_ptr;
4203+
q.len = name_len;
4204+
q.hash = full_name_hash(q.name, q.len);
4205+
tmp = d_lookup(filp->f_dentry, &q);
4206+
if (!tmp) {
4207+
struct btrfs_key *newkey;
4208+
4209+
newkey = kzalloc(sizeof(struct btrfs_key),
4210+
GFP_NOFS);
4211+
if (!newkey)
4212+
goto no_dentry;
4213+
tmp = d_alloc(filp->f_dentry, &q);
4214+
if (!tmp) {
4215+
kfree(newkey);
4216+
dput(tmp);
4217+
goto no_dentry;
4218+
}
4219+
memcpy(newkey, &location,
4220+
sizeof(struct btrfs_key));
4221+
tmp->d_fsdata = newkey;
4222+
tmp->d_flags |= DCACHE_NEED_LOOKUP;
4223+
d_rehash(tmp);
4224+
dput(tmp);
4225+
} else {
4226+
dput(tmp);
4227+
}
4228+
no_dentry:
41874229
/* is this a reference to our own snapshot? If so
41884230
* skip it
41894231
*/
@@ -7430,4 +7472,5 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
74307472

74317473
const struct dentry_operations btrfs_dentry_operations = {
74327474
.d_delete = btrfs_dentry_delete,
7475+
.d_release = btrfs_dentry_release,
74337476
};

fs/dcache.c

+27-42
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,27 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
301301
return parent;
302302
}
303303

304+
/*
305+
* Unhash a dentry without inserting an RCU walk barrier or checking that
306+
* dentry->d_lock is locked. The caller must take care of that, if
307+
* appropriate.
308+
*/
309+
static void __d_shrink(struct dentry *dentry)
310+
{
311+
if (!d_unhashed(dentry)) {
312+
struct hlist_bl_head *b;
313+
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
314+
b = &dentry->d_sb->s_anon;
315+
else
316+
b = d_hash(dentry->d_parent, dentry->d_name.hash);
317+
318+
hlist_bl_lock(b);
319+
__hlist_bl_del(&dentry->d_hash);
320+
dentry->d_hash.pprev = NULL;
321+
hlist_bl_unlock(b);
322+
}
323+
}
324+
304325
/**
305326
* d_drop - drop a dentry
306327
* @dentry: dentry to drop
@@ -319,17 +340,7 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
319340
void __d_drop(struct dentry *dentry)
320341
{
321342
if (!d_unhashed(dentry)) {
322-
struct hlist_bl_head *b;
323-
if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED))
324-
b = &dentry->d_sb->s_anon;
325-
else
326-
b = d_hash(dentry->d_parent, dentry->d_name.hash);
327-
328-
hlist_bl_lock(b);
329-
__hlist_bl_del(&dentry->d_hash);
330-
dentry->d_hash.pprev = NULL;
331-
hlist_bl_unlock(b);
332-
343+
__d_shrink(dentry);
333344
dentry_rcuwalk_barrier(dentry);
334345
}
335346
}
@@ -828,44 +839,24 @@ EXPORT_SYMBOL(shrink_dcache_sb);
828839
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
829840
{
830841
struct dentry *parent;
831-
unsigned detached = 0;
832842

833843
BUG_ON(!IS_ROOT(dentry));
834844

835-
/* detach this root from the system */
836-
spin_lock(&dentry->d_lock);
837-
dentry_lru_del(dentry);
838-
__d_drop(dentry);
839-
spin_unlock(&dentry->d_lock);
840-
841845
for (;;) {
842846
/* descend to the first leaf in the current subtree */
843-
while (!list_empty(&dentry->d_subdirs)) {
844-
struct dentry *loop;
845-
846-
/* this is a branch with children - detach all of them
847-
* from the system in one go */
848-
spin_lock(&dentry->d_lock);
849-
list_for_each_entry(loop, &dentry->d_subdirs,
850-
d_u.d_child) {
851-
spin_lock_nested(&loop->d_lock,
852-
DENTRY_D_LOCK_NESTED);
853-
dentry_lru_del(loop);
854-
__d_drop(loop);
855-
spin_unlock(&loop->d_lock);
856-
}
857-
spin_unlock(&dentry->d_lock);
858-
859-
/* move to the first child */
847+
while (!list_empty(&dentry->d_subdirs))
860848
dentry = list_entry(dentry->d_subdirs.next,
861849
struct dentry, d_u.d_child);
862-
}
863850

864851
/* consume the dentries from this leaf up through its parents
865852
* until we find one with children or run out altogether */
866853
do {
867854
struct inode *inode;
868855

856+
/* detach from the system */
857+
dentry_lru_del(dentry);
858+
__d_shrink(dentry);
859+
869860
if (dentry->d_count != 0) {
870861
printk(KERN_ERR
871862
"BUG: Dentry %p{i=%lx,n=%s}"
@@ -886,14 +877,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
886877
list_del(&dentry->d_u.d_child);
887878
} else {
888879
parent = dentry->d_parent;
889-
spin_lock(&parent->d_lock);
890880
parent->d_count--;
891881
list_del(&dentry->d_u.d_child);
892-
spin_unlock(&parent->d_lock);
893882
}
894883

895-
detached++;
896-
897884
inode = dentry->d_inode;
898885
if (inode) {
899886
dentry->d_inode = NULL;
@@ -938,9 +925,7 @@ void shrink_dcache_for_umount(struct super_block *sb)
938925

939926
dentry = sb->s_root;
940927
sb->s_root = NULL;
941-
spin_lock(&dentry->d_lock);
942928
dentry->d_count--;
943-
spin_unlock(&dentry->d_lock);
944929
shrink_dcache_for_umount_subtree(dentry);
945930

946931
while (!hlist_bl_empty(&sb->s_anon)) {

fs/ext2/acl.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,10 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
194194
case ACL_TYPE_ACCESS:
195195
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
196196
if (acl) {
197-
mode_t mode = inode->i_mode;
198-
error = posix_acl_equiv_mode(acl, &mode);
197+
error = posix_acl_equiv_mode(acl, &inode->i_mode);
199198
if (error < 0)
200199
return error;
201200
else {
202-
inode->i_mode = mode;
203201
inode->i_ctime = CURRENT_TIME_SEC;
204202
mark_inode_dirty(inode);
205203
if (error == 0)
@@ -253,16 +251,14 @@ ext2_init_acl(struct inode *inode, struct inode *dir)
253251
inode->i_mode &= ~current_umask();
254252
}
255253
if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
256-
mode_t mode = inode->i_mode;
257254
if (S_ISDIR(inode->i_mode)) {
258255
error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
259256
if (error)
260257
goto cleanup;
261258
}
262-
error = posix_acl_create(&acl, GFP_KERNEL, &mode);
259+
error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
263260
if (error < 0)
264261
return error;
265-
inode->i_mode = mode;
266262
if (error > 0) {
267263
/* This is an extended ACL */
268264
error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);

0 commit comments

Comments
 (0)