Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3020a1f5 authored by Steve French's avatar Steve French
Browse files

[CIFS] Fix scheduling while atomic when pending writes at file close time


Fix the case in which readdir reset file type when SFU mount option
specified.

Also fix sfu related functions to not request EAs (xattrs) when not
configured in Kconfig

Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 87c89dd7
Loading
Loading
Loading
Loading
+31 −16
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
		inode->i_ctime =
		    cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
		inode->i_mode = le64_to_cpu(findData.Permissions);
		/* since we set the inode type below we need to mask off
                   to avoid strange results if bits set above */
                        inode->i_mode &= ~S_IFMT;
		if (type == UNIX_FILE) {
			inode->i_mode |= S_IFREG;
		} else if (type == UNIX_SYMLINK) {
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
			inode->i_mode |= S_IFIFO;
		} else if (type == UNIX_SOCKET) {
			inode->i_mode |= S_IFSOCK;
		} else {
			/* safest to call it a file if we do not know */
			inode->i_mode |= S_IFREG;
			cFYI(1,("unknown type %d",type));
		}
		inode->i_uid = le64_to_cpu(findData.Uid);
		inode->i_gid = le64_to_cpu(findData.Gid);
@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
				 8 /* length */, 0 /* offset */,
				 &bytes_read, &pbuf);
		if((rc == 0) && (bytes_read == 8)) {
			cERROR(1,("intx %s" ,pbuf));
			if(memcmp("IntxBLK", pbuf, 8) == 0) {
				cFYI(1,("Block device"));
				inode->i_mode = S_IFBLK;
				inode->i_mode |= S_IFBLK;
			} else if(memcmp("IntxCHR", pbuf, 8) == 0) {
				cFYI(1,("Char device"));
				inode->i_mode = S_IFCHR;
				inode->i_mode |= S_IFCHR;
			} else if(memcmp("IntxLNK", pbuf, 7) == 0) {
				cFYI(1,("Symlink"));
				inode->i_mode = S_IFLNK;
			} else
				inode->i_mode = S_IFREG; /* then it is a file */
				inode->i_mode |= S_IFLNK;
			} 
		} else {
			inode->i_mode |= S_IFREG; /* then it is a file */
			rc = -EOPNOTSUPP; /* or some unknown SFU type */	
			 
		}
		
		CIFSSMBClose(xid, pTcon, netfid);
@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode,
			const unsigned char *path,
			struct cifs_sb_info *cifs_sb, int xid)
{
#ifdef CONFIG_CIFS_XATTR
	ssize_t rc;
	char ea_value[4];
	__u32 mode;
@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode,
		return (int)rc;
	else if (rc > 3) {
		mode = le32_to_cpu(*((__le32 *)ea_value));
		cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
		inode->i_mode = (mode &  SFBITS_MASK) | inode->i_mode;
		cFYI(1,("special mode bits 0%o", mode));
		return 0;
	} else {
		return 0;
	}
#else
	return -EOPNOTSUPP;
#endif

		
}

@@ -416,7 +428,9 @@ int cifs_get_inode_info(struct inode **pinode,
		if (atomic_read(&cifsInfo->inUse) == 0)
			/* new inode, can safely set these fields */
			inode->i_mode = cifs_sb->mnt_file_mode;

		else /* since we set the inode type below we need to mask off
		     to avoid strange results if type changes and both get orred in */ 
			inode->i_mode &= ~S_IFMT; 
/*		if (attr & ATTR_REPARSE)  */
		/* We no longer handle these as symlinks because we could not
		   follow them due to the absolute path with drive letter */
@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode,
					 cifs_sb, xid)) {
				cFYI(1,("Unrecognized sfu inode type"));
			}
			cFYI(1,("sfu mode 0%o",inode->i_mode));
		} else {
			inode->i_mode |= S_IFREG;
			/* treat the dos attribute of read-only as read-only
+25 −6
Original line number Diff line number Diff line
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
		tmp_inode->i_gid = cifs_sb->mnt_gid;
		/* set default mode. will override for dirs below */
		tmp_inode->i_mode = cifs_sb->mnt_file_mode;
	} else {
		/* mask off the type bits since it gets set
		below and we do not want to get two type
		bits set */
		tmp_inode->i_mode &= ~S_IFMT;
	}

	if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
		}
		tmp_inode->i_mode |= S_IFDIR;
	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 
		   (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
		   (attr & ATTR_SYSTEM)) {
		if (end_of_file == 0)  {
			*pobject_type = DT_FIFO;
			tmp_inode->i_mode |= S_IFIFO;
/* BB Finish for SFU style symlinks and devies */
/*	} else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
		(attr & ATTR_SYSTEM) && ) { */
		} else {
			/* rather than get the type here, we mark the
			inode as needing revalidate and get the real type
			(blk vs chr vs. symlink) later ie in lookup */
			*pobject_type = DT_REG;
			tmp_inode->i_mode |= S_IFREG; 
			cifsInfo->time = 0;	
		}
/* we no longer mark these because we could not follow them */
/*        } else if (attr & ATTR_REPARSE) {
                *pobject_type = DT_LNK;
@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
	    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));

	tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
	/* since we set the inode type below we need to mask off type
           to avoid strange results if bits above were corrupt */
        tmp_inode->i_mode &= ~S_IFMT;
	if (type == UNIX_FILE) {
		*pobject_type = DT_REG;
		tmp_inode->i_mode |= S_IFREG;
@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
	} else if (type == UNIX_SOCKET) {
		*pobject_type = DT_SOCK;
		tmp_inode->i_mode |= S_IFSOCK;
	} else {
		/* safest to just call it a file */
		*pobject_type = DT_REG;
		tmp_inode->i_mode |= S_IFREG;
		cFYI(1,("unknown inode type %d",type)); 
	}

	tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);