Skip to content

Commit 4d66952

Browse files
author
Al Viro
committed
cifs: have cifs_fattr_to_inode() refuse to change type on live inode
... instead of trying to do that in the callers (and missing some, at that) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 3bcb39b commit 4d66952

4 files changed

Lines changed: 18 additions & 32 deletions

File tree

fs/cifs/cifsproto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
194194
struct cifs_sb_info *cifs_sb);
195195
extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
196196
struct cifs_sb_info *);
197-
extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
197+
extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
198198
extern struct inode *cifs_iget(struct super_block *sb,
199199
struct cifs_fattr *fattr);
200200

fs/cifs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
165165
goto posix_open_ret;
166166
}
167167
} else {
168-
cifs_fattr_to_inode(*pinode, &fattr);
168+
rc = cifs_fattr_to_inode(*pinode, &fattr);
169169
}
170170

171171
posix_open_ret:

fs/cifs/inode.c

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,18 @@ cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
157157
}
158158

159159
/* populate an inode with info from a cifs_fattr struct */
160-
void
160+
int
161161
cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
162162
{
163163
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
164164
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
165165

166+
if (!(inode->i_state & I_NEW) &&
167+
unlikely(inode_wrong_type(inode, fattr->cf_mode))) {
168+
CIFS_I(inode)->time = 0; /* force reval */
169+
return -ESTALE;
170+
}
171+
166172
cifs_revalidate_cache(inode, fattr);
167173

168174
spin_lock(&inode->i_lock);
@@ -219,6 +225,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
219225
inode->i_flags |= S_AUTOMOUNT;
220226
if (inode->i_state & I_NEW)
221227
cifs_set_ops(inode);
228+
return 0;
222229
}
223230

224231
void
@@ -363,7 +370,7 @@ cifs_get_file_info_unix(struct file *filp)
363370
rc = 0;
364371
}
365372

366-
cifs_fattr_to_inode(inode, &fattr);
373+
rc = cifs_fattr_to_inode(inode, &fattr);
367374
free_xid(xid);
368375
return rc;
369376
}
@@ -426,13 +433,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
426433
}
427434

428435
/* if filetype is different, return error */
429-
if (unlikely(inode_wrong_type(*pinode, fattr.cf_mode))) {
430-
CIFS_I(*pinode)->time = 0; /* force reval */
431-
rc = -ESTALE;
432-
goto cgiiu_exit;
433-
}
434-
435-
cifs_fattr_to_inode(*pinode, &fattr);
436+
rc = cifs_fattr_to_inode(*pinode, &fattr);
436437
}
437438

438439
cgiiu_exit:
@@ -782,7 +783,8 @@ cifs_get_file_info(struct file *filp)
782783
*/
783784
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
784785
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
785-
cifs_fattr_to_inode(inode, &fattr);
786+
/* if filetype is different, return error */
787+
rc = cifs_fattr_to_inode(inode, &fattr);
786788
cgfi_exit:
787789
free_xid(xid);
788790
return rc;
@@ -1099,16 +1101,8 @@ cifs_get_inode_info(struct inode **inode,
10991101
rc = -ESTALE;
11001102
goto out;
11011103
}
1102-
11031104
/* if filetype is different, return error */
1104-
if (unlikely(((*inode)->i_mode & S_IFMT) !=
1105-
(fattr.cf_mode & S_IFMT))) {
1106-
CIFS_I(*inode)->time = 0; /* force reval */
1107-
rc = -ESTALE;
1108-
goto out;
1109-
}
1110-
1111-
cifs_fattr_to_inode(*inode, &fattr);
1105+
rc = cifs_fattr_to_inode(*inode, &fattr);
11121106
}
11131107
out:
11141108
cifs_buf_release(smb1_backup_rsp_buf);
@@ -1214,14 +1208,7 @@ smb311_posix_get_inode_info(struct inode **inode,
12141208
}
12151209

12161210
/* if filetype is different, return error */
1217-
if (unlikely(((*inode)->i_mode & S_IFMT) !=
1218-
(fattr.cf_mode & S_IFMT))) {
1219-
CIFS_I(*inode)->time = 0; /* force reval */
1220-
rc = -ESTALE;
1221-
goto out;
1222-
}
1223-
1224-
cifs_fattr_to_inode(*inode, &fattr);
1211+
rc = cifs_fattr_to_inode(*inode, &fattr);
12251212
}
12261213
out:
12271214
cifs_put_tlink(tlink);
@@ -1316,6 +1303,7 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
13161303
}
13171304
}
13181305

1306+
/* can't fail - see cifs_find_inode() */
13191307
cifs_fattr_to_inode(inode, fattr);
13201308
if (sb->s_flags & SB_NOATIME)
13211309
inode->i_flags |= S_NOATIME | S_NOCMTIME;

fs/cifs/readdir.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
119119
/* update inode in place
120120
* if both i_ino and i_mode didn't change */
121121
if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid &&
122-
(inode->i_mode & S_IFMT) ==
123-
(fattr->cf_mode & S_IFMT)) {
124-
cifs_fattr_to_inode(inode, fattr);
122+
cifs_fattr_to_inode(inode, fattr) == 0) {
125123
dput(dentry);
126124
return;
127125
}

0 commit comments

Comments
 (0)