mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
Merge git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French * git://git.samba.org/sfrench/cifs-2.6: cifs: fix dentry refcount leak when opening a FIFO on lookup CIFS: Fix mkdir/rmdir bug for the non-POSIX case
This commit is contained in:
commit
71fece9511
2 changed files with 37 additions and 11 deletions
|
@ -584,10 +584,26 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
* If either that or op not supported returned, follow
|
||||
* the normal lookup.
|
||||
*/
|
||||
if ((rc == 0) || (rc == -ENOENT))
|
||||
switch (rc) {
|
||||
case 0:
|
||||
/*
|
||||
* The server may allow us to open things like
|
||||
* FIFOs, but the client isn't set up to deal
|
||||
* with that. If it's not a regular file, just
|
||||
* close it and proceed as if it were a normal
|
||||
* lookup.
|
||||
*/
|
||||
if (newInode && !S_ISREG(newInode->i_mode)) {
|
||||
CIFSSMBClose(xid, pTcon, fileHandle);
|
||||
break;
|
||||
}
|
||||
case -ENOENT:
|
||||
posix_open = true;
|
||||
else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
|
||||
case -EOPNOTSUPP:
|
||||
break;
|
||||
default:
|
||||
pTcon->broken_posix_open = true;
|
||||
}
|
||||
}
|
||||
if (!posix_open)
|
||||
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
||||
|
|
|
@ -534,6 +534,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
|
|||
if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
|
||||
fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
|
||||
fattr->cf_dtype = DT_DIR;
|
||||
/*
|
||||
* Server can return wrong NumberOfLinks value for directories
|
||||
* when Unix extensions are disabled - fake it.
|
||||
*/
|
||||
fattr->cf_nlink = 2;
|
||||
} else {
|
||||
fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
|
||||
fattr->cf_dtype = DT_REG;
|
||||
|
@ -541,9 +546,9 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
|
|||
/* clear write bits if ATTR_READONLY is set */
|
||||
if (fattr->cf_cifsattrs & ATTR_READONLY)
|
||||
fattr->cf_mode &= ~(S_IWUGO);
|
||||
}
|
||||
|
||||
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
|
||||
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
|
||||
}
|
||||
|
||||
fattr->cf_uid = cifs_sb->mnt_uid;
|
||||
fattr->cf_gid = cifs_sb->mnt_gid;
|
||||
|
@ -1322,7 +1327,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
|
|||
}
|
||||
/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
|
||||
to set uid/gid */
|
||||
inc_nlink(inode);
|
||||
|
||||
cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
|
||||
cifs_fill_uniqueid(inode->i_sb, &fattr);
|
||||
|
@ -1355,7 +1359,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
|
|||
d_drop(direntry);
|
||||
} else {
|
||||
mkdir_get_info:
|
||||
inc_nlink(inode);
|
||||
if (pTcon->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
||||
inode->i_sb, xid);
|
||||
|
@ -1436,6 +1439,11 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
|
|||
}
|
||||
}
|
||||
mkdir_out:
|
||||
/*
|
||||
* Force revalidate to get parent dir info when needed since cached
|
||||
* attributes are invalid now.
|
||||
*/
|
||||
CIFS_I(inode)->time = 0;
|
||||
kfree(full_path);
|
||||
FreeXid(xid);
|
||||
cifs_put_tlink(tlink);
|
||||
|
@ -1475,7 +1483,6 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||
cifs_put_tlink(tlink);
|
||||
|
||||
if (!rc) {
|
||||
drop_nlink(inode);
|
||||
spin_lock(&direntry->d_inode->i_lock);
|
||||
i_size_write(direntry->d_inode, 0);
|
||||
clear_nlink(direntry->d_inode);
|
||||
|
@ -1483,12 +1490,15 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||
}
|
||||
|
||||
cifsInode = CIFS_I(direntry->d_inode);
|
||||
cifsInode->time = 0; /* force revalidate to go get info when
|
||||
needed */
|
||||
/* force revalidate to go get info when needed */
|
||||
cifsInode->time = 0;
|
||||
|
||||
cifsInode = CIFS_I(inode);
|
||||
cifsInode->time = 0; /* force revalidate to get parent dir info
|
||||
since cached search results now invalid */
|
||||
/*
|
||||
* Force revalidate to get parent dir info when needed since cached
|
||||
* attributes are invalid now.
|
||||
*/
|
||||
cifsInode->time = 0;
|
||||
|
||||
direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
|
||||
current_fs_time(inode->i_sb);
|
||||
|
|
Loading…
Reference in a new issue