aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/inode.c51
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
1179static int 1179static int
1180cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, 1180cifs_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