diff options
-rw-r--r-- | fs/cifs/inode.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e74e1bceb416..3d155875f446 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1177,34 +1177,33 @@ unlink_out: | |||
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int | 1179 | static int |
1180 | cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | 1180 | cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, |
1181 | const char *full_path, struct cifs_sb_info *cifs_sb, | 1181 | const char *full_path, struct cifs_sb_info *cifs_sb, |
1182 | struct cifs_tcon *tcon, const unsigned int xid) | 1182 | struct cifs_tcon *tcon, const unsigned int xid) |
1183 | { | 1183 | { |
1184 | int rc = 0; | 1184 | int rc = 0; |
1185 | struct inode *newinode = NULL; | 1185 | struct inode *inode = NULL; |
1186 | 1186 | ||
1187 | if (tcon->unix_ext) | 1187 | if (tcon->unix_ext) |
1188 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, | 1188 | rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb, |
1189 | xid); | 1189 | xid); |
1190 | else | 1190 | else |
1191 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 1191 | rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb, |
1192 | inode->i_sb, xid, NULL); | 1192 | xid, NULL); |
1193 | |||
1193 | if (rc) | 1194 | if (rc) |
1194 | return rc; | 1195 | return rc; |
1195 | 1196 | ||
1196 | d_instantiate(dentry, newinode); | ||
1197 | /* | 1197 | /* |
1198 | * setting nlink not necessary except in cases where we failed to get it | 1198 | * setting nlink not necessary except in cases where we failed to get it |
1199 | * from the server or was set bogus | 1199 | * from the server or was set bogus. Also, since this is a brand new |
1200 | * inode, no need to grab the i_lock before setting the i_nlink. | ||
1200 | */ | 1201 | */ |
1201 | spin_lock(&dentry->d_inode->i_lock); | 1202 | if (inode->i_nlink < 2) |
1202 | if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) | 1203 | set_nlink(inode, 2); |
1203 | set_nlink(dentry->d_inode, 2); | ||
1204 | spin_unlock(&dentry->d_inode->i_lock); | ||
1205 | mode &= ~current_umask(); | 1204 | mode &= ~current_umask(); |
1206 | /* must turn on setgid bit if parent dir has it */ | 1205 | /* must turn on setgid bit if parent dir has it */ |
1207 | if (inode->i_mode & S_ISGID) | 1206 | if (parent->i_mode & S_ISGID) |
1208 | mode |= S_ISGID; | 1207 | mode |= S_ISGID; |
1209 | 1208 | ||
1210 | if (tcon->unix_ext) { | 1209 | if (tcon->unix_ext) { |
@@ -1217,8 +1216,8 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1217 | }; | 1216 | }; |
1218 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 1217 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
1219 | args.uid = (__u64)current_fsuid(); | 1218 | args.uid = (__u64)current_fsuid(); |
1220 | if (inode->i_mode & S_ISGID) | 1219 | if (parent->i_mode & S_ISGID) |
1221 | args.gid = (__u64)inode->i_gid; | 1220 | args.gid = (__u64)parent->i_gid; |
1222 | else | 1221 | else |
1223 | args.gid = (__u64)current_fsgid(); | 1222 | args.gid = (__u64)current_fsgid(); |
1224 | } else { | 1223 | } else { |
@@ -1233,22 +1232,20 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1233 | struct TCP_Server_Info *server = tcon->ses->server; | 1232 | struct TCP_Server_Info *server = tcon->ses->server; |
1234 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && | 1233 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
1235 | (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) | 1234 | (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) |
1236 | server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, | 1235 | server->ops->mkdir_setinfo(inode, full_path, cifs_sb, |
1237 | tcon, xid); | 1236 | tcon, xid); |
1238 | if (dentry->d_inode) { | 1237 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
1239 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 1238 | inode->i_mode = (mode | S_IFDIR); |
1240 | dentry->d_inode->i_mode = (mode | S_IFDIR); | 1239 | |
1241 | 1240 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | |
1242 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 1241 | inode->i_uid = current_fsuid(); |
1243 | dentry->d_inode->i_uid = current_fsuid(); | 1242 | if (inode->i_mode & S_ISGID) |
1244 | if (inode->i_mode & S_ISGID) | 1243 | inode->i_gid = parent->i_gid; |
1245 | dentry->d_inode->i_gid = inode->i_gid; | 1244 | else |
1246 | else | 1245 | inode->i_gid = current_fsgid(); |
1247 | dentry->d_inode->i_gid = | ||
1248 | current_fsgid(); | ||
1249 | } | ||
1250 | } | 1246 | } |
1251 | } | 1247 | } |
1248 | d_instantiate(dentry, inode); | ||
1252 | return rc; | 1249 | return rc; |
1253 | } | 1250 | } |
1254 | 1251 | ||