brintos

brintos / linux-shallow public Read only

0
0
Text · 86.6 KiB · eff3f57 Raw
3265 lines · c
1// SPDX-License-Identifier: LGPL-2.12/*3 *4 *   Copyright (C) International Business Machines  Corp., 2002,20105 *   Author(s): Steve French (sfrench@us.ibm.com)6 *7 */8#include <linux/fs.h>9#include <linux/stat.h>10#include <linux/slab.h>11#include <linux/pagemap.h>12#include <linux/freezer.h>13#include <linux/sched/signal.h>14#include <linux/wait_bit.h>15#include <linux/fiemap.h>16#include <asm/div64.h>17#include "cifsfs.h"18#include "cifspdu.h"19#include "cifsglob.h"20#include "cifsproto.h"21#include "smb2proto.h"22#include "cifs_debug.h"23#include "cifs_fs_sb.h"24#include "cifs_unicode.h"25#include "fscache.h"26#include "fs_context.h"27#include "cifs_ioctl.h"28#include "cached_dir.h"29#include "reparse.h"30 31/*32 * Set parameters for the netfs library33 */34static void cifs_set_netfs_context(struct inode *inode)35{36	struct cifsInodeInfo *cifs_i = CIFS_I(inode);37 38	netfs_inode_init(&cifs_i->netfs, &cifs_req_ops, true);39}40 41static void cifs_set_ops(struct inode *inode)42{43	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);44	struct netfs_inode *ictx = netfs_inode(inode);45 46	switch (inode->i_mode & S_IFMT) {47	case S_IFREG:48		inode->i_op = &cifs_file_inode_ops;49		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {50			set_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags);51			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)52				inode->i_fop = &cifs_file_direct_nobrl_ops;53			else54				inode->i_fop = &cifs_file_direct_ops;55		} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {56			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)57				inode->i_fop = &cifs_file_strict_nobrl_ops;58			else59				inode->i_fop = &cifs_file_strict_ops;60		} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)61			inode->i_fop = &cifs_file_nobrl_ops;62		else { /* not direct, send byte range locks */63			inode->i_fop = &cifs_file_ops;64		}65 66		/* check if server can support readahead */67		if (cifs_sb_master_tcon(cifs_sb)->ses->server->max_read <68				PAGE_SIZE + MAX_CIFS_HDR_SIZE)69			inode->i_data.a_ops = &cifs_addr_ops_smallbuf;70		else71			inode->i_data.a_ops = &cifs_addr_ops;72		mapping_set_large_folios(inode->i_mapping);73		break;74	case S_IFDIR:75		if (IS_AUTOMOUNT(inode)) {76			inode->i_op = &cifs_namespace_inode_operations;77		} else {78			inode->i_op = &cifs_dir_inode_ops;79			inode->i_fop = &cifs_dir_ops;80		}81		break;82	case S_IFLNK:83		inode->i_op = &cifs_symlink_inode_ops;84		break;85	default:86		init_special_inode(inode, inode->i_mode, inode->i_rdev);87		break;88	}89}90 91/* check inode attributes against fattr. If they don't match, tag the92 * inode for cache invalidation93 */94static void95cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)96{97	struct cifs_fscache_inode_coherency_data cd;98	struct cifsInodeInfo *cifs_i = CIFS_I(inode);99	struct timespec64 mtime;100 101	cifs_dbg(FYI, "%s: revalidating inode %llu\n",102		 __func__, cifs_i->uniqueid);103 104	if (inode->i_state & I_NEW) {105		cifs_dbg(FYI, "%s: inode %llu is new\n",106			 __func__, cifs_i->uniqueid);107		return;108	}109 110	/* don't bother with revalidation if we have an oplock */111	if (CIFS_CACHE_READ(cifs_i)) {112		cifs_dbg(FYI, "%s: inode %llu is oplocked\n",113			 __func__, cifs_i->uniqueid);114		return;115	}116 117	 /* revalidate if mtime or size have changed */118	fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);119	mtime = inode_get_mtime(inode);120	if (timespec64_equal(&mtime, &fattr->cf_mtime) &&121	    cifs_i->netfs.remote_i_size == fattr->cf_eof) {122		cifs_dbg(FYI, "%s: inode %llu is unchanged\n",123			 __func__, cifs_i->uniqueid);124		return;125	}126 127	cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n",128		 __func__, cifs_i->uniqueid);129	set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags);130	/* Invalidate fscache cookie */131	cifs_fscache_fill_coherency(&cifs_i->netfs.inode, &cd);132	fscache_invalidate(cifs_inode_cookie(inode), &cd, i_size_read(inode), 0);133}134 135/*136 * copy nlink to the inode, unless it wasn't provided.  Provide137 * sane values if we don't have an existing one and none was provided138 */139static void140cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)141{142	/*143	 * if we're in a situation where we can't trust what we144	 * got from the server (readdir, some non-unix cases)145	 * fake reasonable values146	 */147	if (fattr->cf_flags & CIFS_FATTR_UNKNOWN_NLINK) {148		/* only provide fake values on a new inode */149		if (inode->i_state & I_NEW) {150			if (fattr->cf_cifsattrs & ATTR_DIRECTORY)151				set_nlink(inode, 2);152			else153				set_nlink(inode, 1);154		}155		return;156	}157 158	/* we trust the server, so update it */159	set_nlink(inode, fattr->cf_nlink);160}161 162/* populate an inode with info from a cifs_fattr struct */163int164cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,165		    bool from_readdir)166{167	struct cifsInodeInfo *cifs_i = CIFS_I(inode);168	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);169 170	if (!(inode->i_state & I_NEW) &&171	    unlikely(inode_wrong_type(inode, fattr->cf_mode))) {172		CIFS_I(inode)->time = 0; /* force reval */173		return -ESTALE;174	}175	if (inode->i_state & I_NEW)176		CIFS_I(inode)->netfs.zero_point = fattr->cf_eof;177 178	cifs_revalidate_cache(inode, fattr);179 180	spin_lock(&inode->i_lock);181	fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);182	fattr->cf_atime = timestamp_truncate(fattr->cf_atime, inode);183	fattr->cf_ctime = timestamp_truncate(fattr->cf_ctime, inode);184	/* we do not want atime to be less than mtime, it broke some apps */185	if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0)186		inode_set_atime_to_ts(inode, fattr->cf_mtime);187	else188		inode_set_atime_to_ts(inode, fattr->cf_atime);189	inode_set_mtime_to_ts(inode, fattr->cf_mtime);190	inode_set_ctime_to_ts(inode, fattr->cf_ctime);191	inode->i_rdev = fattr->cf_rdev;192	cifs_nlink_fattr_to_inode(inode, fattr);193	inode->i_uid = fattr->cf_uid;194	inode->i_gid = fattr->cf_gid;195 196	/* if dynperm is set, don't clobber existing mode */197	if (inode->i_state & I_NEW ||198	    !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))199		inode->i_mode = fattr->cf_mode;200 201	cifs_i->cifsAttrs = fattr->cf_cifsattrs;202	cifs_i->reparse_tag = fattr->cf_cifstag;203 204	if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)205		cifs_i->time = 0;206	else207		cifs_i->time = jiffies;208 209	if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)210		set_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);211	else212		clear_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags);213 214	cifs_i->netfs.remote_i_size = fattr->cf_eof;215	/*216	 * Can't safely change the file size here if the client is writing to217	 * it due to potential races.218	 */219	if (is_size_safe_to_change(cifs_i, fattr->cf_eof, from_readdir)) {220		i_size_write(inode, fattr->cf_eof);221 222		/*223		 * i_blocks is not related to (i_size / i_blksize),224		 * but instead 512 byte (2**9) size is required for225		 * calculating num blocks.226		 */227		inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;228	}229 230	if (S_ISLNK(fattr->cf_mode) && fattr->cf_symlink_target) {231		kfree(cifs_i->symlink_target);232		cifs_i->symlink_target = fattr->cf_symlink_target;233		fattr->cf_symlink_target = NULL;234	}235	spin_unlock(&inode->i_lock);236 237	if (fattr->cf_flags & CIFS_FATTR_JUNCTION)238		inode->i_flags |= S_AUTOMOUNT;239	if (inode->i_state & I_NEW) {240		cifs_set_netfs_context(inode);241		cifs_set_ops(inode);242	}243	return 0;244}245 246void247cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)248{249	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);250 251	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)252		return;253 254	fattr->cf_uniqueid = iunique(sb, ROOT_I);255}256 257/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */258void259cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,260			 struct cifs_sb_info *cifs_sb)261{262	memset(fattr, 0, sizeof(*fattr));263	fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);264	fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);265	fattr->cf_eof = le64_to_cpu(info->EndOfFile);266 267	fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);268	fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);269	fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);270	/* old POSIX extensions don't get create time */271 272	fattr->cf_mode = le64_to_cpu(info->Permissions);273 274	/*275	 * Since we set the inode type below we need to mask off276	 * to avoid strange results if bits set above.277	 */278	fattr->cf_mode &= ~S_IFMT;279	switch (le32_to_cpu(info->Type)) {280	case UNIX_FILE:281		fattr->cf_mode |= S_IFREG;282		fattr->cf_dtype = DT_REG;283		break;284	case UNIX_SYMLINK:285		fattr->cf_mode |= S_IFLNK;286		fattr->cf_dtype = DT_LNK;287		break;288	case UNIX_DIR:289		fattr->cf_mode |= S_IFDIR;290		fattr->cf_dtype = DT_DIR;291		break;292	case UNIX_CHARDEV:293		fattr->cf_mode |= S_IFCHR;294		fattr->cf_dtype = DT_CHR;295		fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),296				       le64_to_cpu(info->DevMinor) & MINORMASK);297		break;298	case UNIX_BLOCKDEV:299		fattr->cf_mode |= S_IFBLK;300		fattr->cf_dtype = DT_BLK;301		fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),302				       le64_to_cpu(info->DevMinor) & MINORMASK);303		break;304	case UNIX_FIFO:305		fattr->cf_mode |= S_IFIFO;306		fattr->cf_dtype = DT_FIFO;307		break;308	case UNIX_SOCKET:309		fattr->cf_mode |= S_IFSOCK;310		fattr->cf_dtype = DT_SOCK;311		break;312	default:313		/* safest to call it a file if we do not know */314		fattr->cf_mode |= S_IFREG;315		fattr->cf_dtype = DT_REG;316		cifs_dbg(FYI, "unknown type %d\n", le32_to_cpu(info->Type));317		break;318	}319 320	fattr->cf_uid = cifs_sb->ctx->linux_uid;321	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {322		u64 id = le64_to_cpu(info->Uid);323		if (id < ((uid_t)-1)) {324			kuid_t uid = make_kuid(&init_user_ns, id);325			if (uid_valid(uid))326				fattr->cf_uid = uid;327		}328	}329	330	fattr->cf_gid = cifs_sb->ctx->linux_gid;331	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {332		u64 id = le64_to_cpu(info->Gid);333		if (id < ((gid_t)-1)) {334			kgid_t gid = make_kgid(&init_user_ns, id);335			if (gid_valid(gid))336				fattr->cf_gid = gid;337		}338	}339 340	fattr->cf_nlink = le64_to_cpu(info->Nlinks);341}342 343/*344 * Fill a cifs_fattr struct with fake inode info.345 *346 * Needed to setup cifs_fattr data for the directory which is the347 * junction to the new submount (ie to setup the fake directory348 * which represents a DFS referral or reparse mount point).349 */350static void cifs_create_junction_fattr(struct cifs_fattr *fattr,351				       struct super_block *sb)352{353	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);354 355	cifs_dbg(FYI, "%s: creating fake fattr\n", __func__);356 357	memset(fattr, 0, sizeof(*fattr));358	fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;359	fattr->cf_uid = cifs_sb->ctx->linux_uid;360	fattr->cf_gid = cifs_sb->ctx->linux_gid;361	ktime_get_coarse_real_ts64(&fattr->cf_mtime);362	fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;363	fattr->cf_nlink = 2;364	fattr->cf_flags = CIFS_FATTR_JUNCTION;365}366 367/* Update inode with final fattr data */368static int update_inode_info(struct super_block *sb,369			     struct cifs_fattr *fattr,370			     struct inode **inode)371{372	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);373	int rc = 0;374 375	if (!*inode) {376		*inode = cifs_iget(sb, fattr);377		if (!*inode)378			rc = -ENOMEM;379		return rc;380	}381	/* We already have inode, update it.382	 *383	 * If file type or uniqueid is different, return error.384	 */385	if (unlikely((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&386		     CIFS_I(*inode)->uniqueid != fattr->cf_uniqueid)) {387		CIFS_I(*inode)->time = 0; /* force reval */388		return -ESTALE;389	}390	return cifs_fattr_to_inode(*inode, fattr, false);391}392 393#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY394static int395cifs_get_file_info_unix(struct file *filp)396{397	int rc;398	unsigned int xid;399	FILE_UNIX_BASIC_INFO find_data;400	struct cifs_fattr fattr = {};401	struct inode *inode = file_inode(filp);402	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);403	struct cifsFileInfo *cfile = filp->private_data;404	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);405 406	xid = get_xid();407 408	if (cfile->symlink_target) {409		fattr.cf_symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);410		if (!fattr.cf_symlink_target) {411			rc = -ENOMEM;412			goto cifs_gfiunix_out;413		}414	}415 416	rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data);417	if (!rc) {418		cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);419	} else if (rc == -EREMOTE) {420		cifs_create_junction_fattr(&fattr, inode->i_sb);421	} else422		goto cifs_gfiunix_out;423 424	rc = cifs_fattr_to_inode(inode, &fattr, false);425 426cifs_gfiunix_out:427	free_xid(xid);428	return rc;429}430 431static int cifs_get_unix_fattr(const unsigned char *full_path,432			       struct super_block *sb,433			       struct cifs_fattr *fattr,434			       struct inode **pinode,435			       const unsigned int xid)436{437	struct TCP_Server_Info *server;438	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);439	FILE_UNIX_BASIC_INFO find_data;440	struct cifs_tcon *tcon;441	struct tcon_link *tlink;442	int rc, tmprc;443 444	cifs_dbg(FYI, "Getting info on %s\n", full_path);445 446	tlink = cifs_sb_tlink(cifs_sb);447	if (IS_ERR(tlink))448		return PTR_ERR(tlink);449	tcon = tlink_tcon(tlink);450	server = tcon->ses->server;451 452	/* could have done a find first instead but this returns more info */453	rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,454				  cifs_sb->local_nls, cifs_remap(cifs_sb));455	cifs_dbg(FYI, "%s: query path info: rc = %d\n", __func__, rc);456	cifs_put_tlink(tlink);457 458	if (!rc) {459		cifs_unix_basic_to_fattr(fattr, &find_data, cifs_sb);460	} else if (rc == -EREMOTE) {461		cifs_create_junction_fattr(fattr, sb);462		rc = 0;463	} else {464		return rc;465	}466 467	if (!*pinode)468		cifs_fill_uniqueid(sb, fattr);469 470	/* check for Minshall+French symlinks */471	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {472		tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);473		cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);474	}475 476	if (S_ISLNK(fattr->cf_mode) && !fattr->cf_symlink_target) {477		if (!server->ops->query_symlink)478			return -EOPNOTSUPP;479		rc = server->ops->query_symlink(xid, tcon,480						cifs_sb, full_path,481						&fattr->cf_symlink_target);482		cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc);483	}484	return rc;485}486 487int cifs_get_inode_info_unix(struct inode **pinode,488			     const unsigned char *full_path,489			     struct super_block *sb, unsigned int xid)490{491	struct cifs_fattr fattr = {};492	int rc;493 494	rc = cifs_get_unix_fattr(full_path, sb, &fattr, pinode, xid);495	if (rc)496		goto out;497 498	rc = update_inode_info(sb, &fattr, pinode);499out:500	kfree(fattr.cf_symlink_target);501	return rc;502}503#else504static inline int cifs_get_unix_fattr(const unsigned char *full_path,505				      struct super_block *sb,506				      struct cifs_fattr *fattr,507				      struct inode **pinode,508				      const unsigned int xid)509{510	return -EOPNOTSUPP;511}512 513int cifs_get_inode_info_unix(struct inode **pinode,514			     const unsigned char *full_path,515			     struct super_block *sb, unsigned int xid)516{517	return -EOPNOTSUPP;518}519#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */520 521static int522cifs_sfu_type(struct cifs_fattr *fattr, const char *path,523	      struct cifs_sb_info *cifs_sb, unsigned int xid)524{525	int rc;526	__u32 oplock;527	struct tcon_link *tlink;528	struct cifs_tcon *tcon;529	struct cifs_fid fid;530	struct cifs_open_parms oparms;531	struct cifs_io_parms io_parms = {0};532	char *symlink_buf_utf16;533	unsigned int symlink_len_utf16;534	char buf[24];535	unsigned int bytes_read;536	char *pbuf;537	int buf_type = CIFS_NO_BUFFER;538 539	pbuf = buf;540 541	fattr->cf_mode &= ~S_IFMT;542 543	if (fattr->cf_eof == 0) {544		cifs_dbg(FYI, "Fifo\n");545		fattr->cf_mode |= S_IFIFO;546		fattr->cf_dtype = DT_FIFO;547		return 0;548	} else if (fattr->cf_eof > 1 && fattr->cf_eof < 8) {549		fattr->cf_mode |= S_IFREG;550		fattr->cf_dtype = DT_REG;551		return -EINVAL;	 /* EOPNOTSUPP? */552	}553 554	tlink = cifs_sb_tlink(cifs_sb);555	if (IS_ERR(tlink))556		return PTR_ERR(tlink);557	tcon = tlink_tcon(tlink);558 559	oparms = (struct cifs_open_parms) {560		.tcon = tcon,561		.cifs_sb = cifs_sb,562		.desired_access = GENERIC_READ,563		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),564		.disposition = FILE_OPEN,565		.path = path,566		.fid = &fid,567	};568 569	if (tcon->ses->server->oplocks)570		oplock = REQ_OPLOCK;571	else572		oplock = 0;573	rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL);574	if (rc) {575		cifs_dbg(FYI, "check sfu type of %s, open rc = %d\n", path, rc);576		cifs_put_tlink(tlink);577		return rc;578	}579 580	/* Read header */581	io_parms.netfid = fid.netfid;582	io_parms.pid = current->tgid;583	io_parms.tcon = tcon;584	io_parms.offset = 0;585	io_parms.length = 24;586 587	rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms,588					&bytes_read, &pbuf, &buf_type);589	if ((rc == 0) && (bytes_read >= 8)) {590		if (memcmp("IntxBLK\0", pbuf, 8) == 0) {591			cifs_dbg(FYI, "Block device\n");592			fattr->cf_mode |= S_IFBLK;593			fattr->cf_dtype = DT_BLK;594			if (bytes_read == 24) {595				/* we have enough to decode dev num */596				__u64 mjr; /* major */597				__u64 mnr; /* minor */598				mjr = le64_to_cpu(*(__le64 *)(pbuf+8));599				mnr = le64_to_cpu(*(__le64 *)(pbuf+16));600				fattr->cf_rdev = MKDEV(mjr, mnr);601			}602		} else if (memcmp("IntxCHR\0", pbuf, 8) == 0) {603			cifs_dbg(FYI, "Char device\n");604			fattr->cf_mode |= S_IFCHR;605			fattr->cf_dtype = DT_CHR;606			if (bytes_read == 24) {607				/* we have enough to decode dev num */608				__u64 mjr; /* major */609				__u64 mnr; /* minor */610				mjr = le64_to_cpu(*(__le64 *)(pbuf+8));611				mnr = le64_to_cpu(*(__le64 *)(pbuf+16));612				fattr->cf_rdev = MKDEV(mjr, mnr);613			}614		} else if (memcmp("LnxSOCK", pbuf, 8) == 0) {615			cifs_dbg(FYI, "Socket\n");616			fattr->cf_mode |= S_IFSOCK;617			fattr->cf_dtype = DT_SOCK;618		} else if (memcmp("IntxLNK\1", pbuf, 8) == 0) {619			cifs_dbg(FYI, "Symlink\n");620			fattr->cf_mode |= S_IFLNK;621			fattr->cf_dtype = DT_LNK;622			if ((fattr->cf_eof > 8) && (fattr->cf_eof % 2 == 0)) {623				symlink_buf_utf16 = kmalloc(fattr->cf_eof-8 + 1, GFP_KERNEL);624				if (symlink_buf_utf16) {625					io_parms.offset = 8;626					io_parms.length = fattr->cf_eof-8 + 1;627					buf_type = CIFS_NO_BUFFER;628					rc = tcon->ses->server->ops->sync_read(xid, &fid, &io_parms,629									       &symlink_len_utf16,630									       &symlink_buf_utf16,631									       &buf_type);632					/*633					 * Check that read buffer has valid length and does not634					 * contain UTF-16 null codepoint (via UniStrnlen() call)635					 * because Linux cannot process symlink with null byte.636					 */637					if ((rc == 0) &&638					    (symlink_len_utf16 > 0) &&639					    (symlink_len_utf16 < fattr->cf_eof-8 + 1) &&640					    (symlink_len_utf16 % 2 == 0) &&641					    (UniStrnlen((wchar_t *)symlink_buf_utf16, symlink_len_utf16/2) == symlink_len_utf16/2)) {642						fattr->cf_symlink_target =643							cifs_strndup_from_utf16(symlink_buf_utf16,644										symlink_len_utf16,645										true,646										cifs_sb->local_nls);647						if (!fattr->cf_symlink_target)648							rc = -ENOMEM;649					}650					kfree(symlink_buf_utf16);651				} else {652					rc = -ENOMEM;653				}654			}655		} else if (memcmp("LnxFIFO", pbuf, 8) == 0) {656			cifs_dbg(FYI, "FIFO\n");657			fattr->cf_mode |= S_IFIFO;658			fattr->cf_dtype = DT_FIFO;659		} else {660			fattr->cf_mode |= S_IFREG; /* file? */661			fattr->cf_dtype = DT_REG;662			rc = -EOPNOTSUPP;663		}664	} else if ((rc == 0) && (bytes_read == 1) && (pbuf[0] == '\0')) {665		cifs_dbg(FYI, "Socket\n");666		fattr->cf_mode |= S_IFSOCK;667		fattr->cf_dtype = DT_SOCK;668	} else {669		fattr->cf_mode |= S_IFREG; /* then it is a file */670		fattr->cf_dtype = DT_REG;671		rc = -EOPNOTSUPP; /* or some unknown SFU type */672	}673 674	tcon->ses->server->ops->close(xid, tcon, &fid);675	cifs_put_tlink(tlink);676	return rc;677}678 679#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */680 681/*682 * Fetch mode bits as provided by SFU.683 *684 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?685 */686static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,687			 struct cifs_sb_info *cifs_sb, unsigned int xid)688{689#ifdef CONFIG_CIFS_XATTR690	ssize_t rc;691	char ea_value[4];692	__u32 mode;693	struct tcon_link *tlink;694	struct cifs_tcon *tcon;695 696	tlink = cifs_sb_tlink(cifs_sb);697	if (IS_ERR(tlink))698		return PTR_ERR(tlink);699	tcon = tlink_tcon(tlink);700 701	if (tcon->ses->server->ops->query_all_EAs == NULL) {702		cifs_put_tlink(tlink);703		return -EOPNOTSUPP;704	}705 706	rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path,707			"SETFILEBITS", ea_value, 4 /* size of buf */,708			cifs_sb);709	cifs_put_tlink(tlink);710	if (rc < 0)711		return (int)rc;712	else if (rc > 3) {713		mode = le32_to_cpu(*((__le32 *)ea_value));714		fattr->cf_mode &= ~SFBITS_MASK;715		cifs_dbg(FYI, "special bits 0%o org mode 0%o\n",716			 mode, fattr->cf_mode);717		fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;718		cifs_dbg(FYI, "special mode bits 0%o\n", mode);719	}720 721	return 0;722#else723	return -EOPNOTSUPP;724#endif725}726 727/* Fill a cifs_fattr struct with info from POSIX info struct */728static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr,729				       struct cifs_open_info_data *data,730				       struct super_block *sb)731{732	struct smb311_posix_qinfo *info = &data->posix_fi;733	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);734	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);735 736	memset(fattr, 0, sizeof(*fattr));737 738	/* no fattr->flags to set */739	fattr->cf_cifsattrs = le32_to_cpu(info->DosAttributes);740	fattr->cf_uniqueid = le64_to_cpu(info->Inode);741 742	if (info->LastAccessTime)743		fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);744	else745		ktime_get_coarse_real_ts64(&fattr->cf_atime);746 747	fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);748	fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);749 750	if (data->adjust_tz) {751		fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;752		fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;753	}754 755	/*756	 * The srv fs device id is overridden on network mount so setting757	 * @fattr->cf_rdev isn't needed here.758	 */759	fattr->cf_eof = le64_to_cpu(info->EndOfFile);760	fattr->cf_bytes = le64_to_cpu(info->AllocationSize);761	fattr->cf_createtime = le64_to_cpu(info->CreationTime);762	fattr->cf_nlink = le32_to_cpu(info->HardLinks);763	fattr->cf_mode = (umode_t) le32_to_cpu(info->Mode);764 765	if (cifs_open_data_reparse(data) &&766	    cifs_reparse_point_to_fattr(cifs_sb, fattr, data))767		goto out_reparse;768 769	fattr->cf_mode &= ~S_IFMT;770	if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {771		fattr->cf_mode |= S_IFDIR;772		fattr->cf_dtype = DT_DIR;773	} else { /* file */774		fattr->cf_mode |= S_IFREG;775		fattr->cf_dtype = DT_REG;776	}777 778out_reparse:779	if (S_ISLNK(fattr->cf_mode)) {780		if (likely(data->symlink_target))781			fattr->cf_eof = strnlen(data->symlink_target, PATH_MAX);782		fattr->cf_symlink_target = data->symlink_target;783		data->symlink_target = NULL;784	}785	sid_to_id(cifs_sb, &data->posix_owner, fattr, SIDOWNER);786	sid_to_id(cifs_sb, &data->posix_group, fattr, SIDGROUP);787 788	cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",789		fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);790}791 792static void cifs_open_info_to_fattr(struct cifs_fattr *fattr,793				    struct cifs_open_info_data *data,794				    struct super_block *sb)795{796	struct smb2_file_all_info *info = &data->fi;797	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);798	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);799 800	memset(fattr, 0, sizeof(*fattr));801	fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);802	if (info->DeletePending)803		fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;804 805	if (info->LastAccessTime)806		fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);807	else808		ktime_get_coarse_real_ts64(&fattr->cf_atime);809 810	fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);811	fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);812 813	if (data->adjust_tz) {814		fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;815		fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;816	}817 818	fattr->cf_eof = le64_to_cpu(info->EndOfFile);819	fattr->cf_bytes = le64_to_cpu(info->AllocationSize);820	fattr->cf_createtime = le64_to_cpu(info->CreationTime);821	fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);822	fattr->cf_uid = cifs_sb->ctx->linux_uid;823	fattr->cf_gid = cifs_sb->ctx->linux_gid;824 825	fattr->cf_mode = cifs_sb->ctx->file_mode;826	if (cifs_open_data_reparse(data) &&827	    cifs_reparse_point_to_fattr(cifs_sb, fattr, data))828		goto out_reparse;829 830	if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {831		fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;832		fattr->cf_dtype = DT_DIR;833		/*834		 * Server can return wrong NumberOfLinks value for directories835		 * when Unix extensions are disabled - fake it.836		 */837		if (!tcon->unix_ext)838			fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;839	} else {840		fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;841		fattr->cf_dtype = DT_REG;842 843		/*844		 * Don't accept zero nlink from non-unix servers unless845		 * delete is pending.  Instead mark it as unknown.846		 */847		if ((fattr->cf_nlink < 1) && !tcon->unix_ext &&848		    !info->DeletePending) {849			cifs_dbg(VFS, "bogus file nlink value %u\n",850				 fattr->cf_nlink);851			fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;852		}853	}854 855	/* clear write bits if ATTR_READONLY is set */856	if (fattr->cf_cifsattrs & ATTR_READONLY)857		fattr->cf_mode &= ~(S_IWUGO);858 859out_reparse:860	if (S_ISLNK(fattr->cf_mode)) {861		if (likely(data->symlink_target))862			fattr->cf_eof = strnlen(data->symlink_target, PATH_MAX);863		fattr->cf_symlink_target = data->symlink_target;864		data->symlink_target = NULL;865	}866}867 868static int869cifs_get_file_info(struct file *filp)870{871	int rc;872	unsigned int xid;873	struct cifs_open_info_data data = {};874	struct cifs_fattr fattr;875	struct inode *inode = file_inode(filp);876	struct cifsFileInfo *cfile = filp->private_data;877	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);878	struct TCP_Server_Info *server = tcon->ses->server;879	struct dentry *dentry = filp->f_path.dentry;880	void *page = alloc_dentry_path();881	const unsigned char *path;882 883	if (!server->ops->query_file_info) {884		free_dentry_path(page);885		return -ENOSYS;886	}887 888	xid = get_xid();889	rc = server->ops->query_file_info(xid, tcon, cfile, &data);890	switch (rc) {891	case 0:892		/* TODO: add support to query reparse tag */893		data.adjust_tz = false;894		if (data.symlink_target) {895			data.symlink = true;896			data.reparse.tag = IO_REPARSE_TAG_SYMLINK;897		}898		path = build_path_from_dentry(dentry, page);899		if (IS_ERR(path)) {900			rc = PTR_ERR(path);901			goto cgfi_exit;902		}903		cifs_open_info_to_fattr(&fattr, &data, inode->i_sb);904		if (fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)905			cifs_mark_open_handles_for_deleted_file(inode, path);906		break;907	case -EREMOTE:908		cifs_create_junction_fattr(&fattr, inode->i_sb);909		break;910	case -EOPNOTSUPP:911	case -EINVAL:912		/*913		 * FIXME: legacy server -- fall back to path-based call?914		 * for now, just skip revalidating and mark inode for915		 * immediate reval.916		 */917		rc = 0;918		CIFS_I(inode)->time = 0;919		goto cgfi_exit;920	default:921		goto cgfi_exit;922	}923 924	/*925	 * don't bother with SFU junk here -- just mark inode as needing926	 * revalidation.927	 */928	fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;929	fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;930	/* if filetype is different, return error */931	rc = cifs_fattr_to_inode(inode, &fattr, false);932cgfi_exit:933	cifs_free_open_info(&data);934	free_dentry_path(page);935	free_xid(xid);936	return rc;937}938 939/* Simple function to return a 64 bit hash of string.  Rarely called */940static __u64 simple_hashstr(const char *str)941{942	const __u64 hash_mult =  1125899906842597ULL; /* a big enough prime */943	__u64 hash = 0;944 945	while (*str)946		hash = (hash + (__u64) *str++) * hash_mult;947 948	return hash;949}950 951#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY952/**953 * cifs_backup_query_path_info - SMB1 fallback code to get ino954 *955 * Fallback code to get file metadata when we don't have access to956 * full_path (EACCES) and have backup creds.957 *958 * @xid:	transaction id used to identify original request in logs959 * @tcon:	information about the server share we have mounted960 * @sb:	the superblock stores info such as disk space available961 * @full_path:	name of the file we are getting the metadata for962 * @resp_buf:	will be set to cifs resp buf and needs to be freed with963 * 		cifs_buf_release() when done with @data964 * @data:	will be set to search info result buffer965 */966static int967cifs_backup_query_path_info(int xid,968			    struct cifs_tcon *tcon,969			    struct super_block *sb,970			    const char *full_path,971			    void **resp_buf,972			    FILE_ALL_INFO **data)973{974	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);975	struct cifs_search_info info = {0};976	u16 flags;977	int rc;978 979	*resp_buf = NULL;980	info.endOfSearch = false;981	if (tcon->unix_ext)982		info.info_level = SMB_FIND_FILE_UNIX;983	else if ((tcon->ses->capabilities &984		  tcon->ses->server->vals->cap_nt_find) == 0)985		info.info_level = SMB_FIND_FILE_INFO_STANDARD;986	else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)987		info.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;988	else /* no srvino useful for fallback to some netapp */989		info.info_level = SMB_FIND_FILE_DIRECTORY_INFO;990 991	flags = CIFS_SEARCH_CLOSE_ALWAYS |992		CIFS_SEARCH_CLOSE_AT_END |993		CIFS_SEARCH_BACKUP_SEARCH;994 995	rc = CIFSFindFirst(xid, tcon, full_path,996			   cifs_sb, NULL, flags, &info, false);997	if (rc)998		return rc;999 1000	*resp_buf = (void *)info.ntwrk_buf_start;1001	*data = (FILE_ALL_INFO *)info.srch_entries_start;1002	return 0;1003}1004#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1005 1006static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb,1007			       struct inode **inode, const char *full_path,1008			       struct cifs_open_info_data *data, struct cifs_fattr *fattr)1009{1010	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1011	struct TCP_Server_Info *server = tcon->ses->server;1012	int rc;1013 1014	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {1015		if (*inode)1016			fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid;1017		else1018			fattr->cf_uniqueid = iunique(sb, ROOT_I);1019		return;1020	}1021 1022	/*1023	 * If we have an inode pass a NULL tcon to ensure we don't1024	 * make a round trip to the server. This only works for SMB2+.1025	 */1026	rc = server->ops->get_srv_inum(xid, *inode ? NULL : tcon, cifs_sb, full_path,1027				       &fattr->cf_uniqueid, data);1028	if (rc) {1029		/*1030		 * If that fails reuse existing ino or generate one1031		 * and disable server ones1032		 */1033		if (*inode)1034			fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid;1035		else {1036			fattr->cf_uniqueid = iunique(sb, ROOT_I);1037			cifs_autodisable_serverino(cifs_sb);1038		}1039		return;1040	}1041 1042	/* If no errors, check for zero root inode (invalid) */1043	if (fattr->cf_uniqueid == 0 && strlen(full_path) == 0) {1044		cifs_dbg(FYI, "Invalid (0) inodenum\n");1045		if (*inode) {1046			/* reuse */1047			fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid;1048		} else {1049			/* make an ino by hashing the UNC */1050			fattr->cf_flags |= CIFS_FATTR_FAKE_ROOT_INO;1051			fattr->cf_uniqueid = simple_hashstr(tcon->tree_name);1052		}1053	}1054}1055 1056static inline bool is_inode_cache_good(struct inode *ino)1057{1058	return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0;1059}1060 1061static int reparse_info_to_fattr(struct cifs_open_info_data *data,1062				 struct super_block *sb,1063				 const unsigned int xid,1064				 struct cifs_tcon *tcon,1065				 const char *full_path,1066				 struct cifs_fattr *fattr)1067{1068	struct TCP_Server_Info *server = tcon->ses->server;1069	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1070	struct kvec rsp_iov, *iov = NULL;1071	int rsp_buftype = CIFS_NO_BUFFER;1072	u32 tag = data->reparse.tag;1073	int rc = 0;1074 1075	if (!tag && server->ops->query_reparse_point) {1076		rc = server->ops->query_reparse_point(xid, tcon, cifs_sb,1077						      full_path, &tag,1078						      &rsp_iov, &rsp_buftype);1079		if (!rc)1080			iov = &rsp_iov;1081	} else if (data->reparse.io.buftype != CIFS_NO_BUFFER &&1082		   data->reparse.io.iov.iov_base) {1083		iov = &data->reparse.io.iov;1084	}1085 1086	rc = -EOPNOTSUPP;1087	data->reparse.tag = tag;1088	if (!data->reparse.tag) {1089		if (server->ops->query_symlink) {1090			rc = server->ops->query_symlink(xid, tcon,1091							cifs_sb, full_path,1092							&data->symlink_target);1093		}1094		if (rc == -EOPNOTSUPP)1095			data->reparse.tag = IO_REPARSE_TAG_INTERNAL;1096	}1097 1098	switch (data->reparse.tag) {1099	case 0: /* SMB1 symlink */1100		break;1101	case IO_REPARSE_TAG_INTERNAL:1102		rc = 0;1103		if (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY) {1104			cifs_create_junction_fattr(fattr, sb);1105			goto out;1106		}1107		break;1108	case IO_REPARSE_TAG_MOUNT_POINT:1109		cifs_create_junction_fattr(fattr, sb);1110		rc = 0;1111		goto out;1112	default:1113		/* Check for cached reparse point data */1114		if (data->symlink_target || data->reparse.buf) {1115			rc = 0;1116		} else if (iov && server->ops->parse_reparse_point) {1117			rc = server->ops->parse_reparse_point(cifs_sb,1118							      iov, data);1119		}1120		break;1121	}1122 1123	if (tcon->posix_extensions)1124		smb311_posix_info_to_fattr(fattr, data, sb);1125	else1126		cifs_open_info_to_fattr(fattr, data, sb);1127out:1128	fattr->cf_cifstag = data->reparse.tag;1129	free_rsp_buf(rsp_buftype, rsp_iov.iov_base);1130	return rc;1131}1132 1133static int cifs_get_fattr(struct cifs_open_info_data *data,1134			  struct super_block *sb, int xid,1135			  const struct cifs_fid *fid,1136			  struct cifs_fattr *fattr,1137			  struct inode **inode,1138			  const char *full_path)1139{1140	struct cifs_open_info_data tmp_data = {};1141	struct cifs_tcon *tcon;1142	struct TCP_Server_Info *server;1143	struct tcon_link *tlink;1144	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1145	void *smb1_backup_rsp_buf = NULL;1146	int rc = 0;1147	int tmprc = 0;1148 1149	tlink = cifs_sb_tlink(cifs_sb);1150	if (IS_ERR(tlink))1151		return PTR_ERR(tlink);1152	tcon = tlink_tcon(tlink);1153	server = tcon->ses->server;1154 1155	/*1156	 * 1. Fetch file metadata if not provided (data)1157	 */1158 1159	if (!data) {1160		rc = server->ops->query_path_info(xid, tcon, cifs_sb,1161						  full_path, &tmp_data);1162		data = &tmp_data;1163	}1164 1165	/*1166	 * 2. Convert it to internal cifs metadata (fattr)1167	 */1168 1169	switch (rc) {1170	case 0:1171		/*1172		 * If the file is a reparse point, it is more complicated1173		 * since we have to check if its reparse tag matches a known1174		 * special file type e.g. symlink or fifo or char etc.1175		 */1176		if (cifs_open_data_reparse(data)) {1177			rc = reparse_info_to_fattr(data, sb, xid, tcon,1178						   full_path, fattr);1179		} else {1180			cifs_open_info_to_fattr(fattr, data, sb);1181		}1182		if (!rc && *inode &&1183		    (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING))1184			cifs_mark_open_handles_for_deleted_file(*inode, full_path);1185		break;1186	case -EREMOTE:1187		/* DFS link, no metadata available on this server */1188		cifs_create_junction_fattr(fattr, sb);1189		rc = 0;1190		break;1191	case -EACCES:1192#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1193		/*1194		 * perm errors, try again with backup flags if possible1195		 *1196		 * For SMB2 and later the backup intent flag1197		 * is already sent if needed on open and there1198		 * is no path based FindFirst operation to use1199		 * to retry with1200		 */1201		if (backup_cred(cifs_sb) && is_smb1_server(server)) {1202			/* for easier reading */1203			FILE_ALL_INFO *fi;1204			FILE_DIRECTORY_INFO *fdi;1205			SEARCH_ID_FULL_DIR_INFO *si;1206 1207			rc = cifs_backup_query_path_info(xid, tcon, sb,1208							 full_path,1209							 &smb1_backup_rsp_buf,1210							 &fi);1211			if (rc)1212				goto out;1213 1214			move_cifs_info_to_smb2(&data->fi, fi);1215			fdi = (FILE_DIRECTORY_INFO *)fi;1216			si = (SEARCH_ID_FULL_DIR_INFO *)fi;1217 1218			cifs_dir_info_to_fattr(fattr, fdi, cifs_sb);1219			fattr->cf_uniqueid = le64_to_cpu(si->UniqueId);1220			/* uniqueid set, skip get inum step */1221			goto handle_mnt_opt;1222		} else {1223			/* nothing we can do, bail out */1224			goto out;1225		}1226#else1227		goto out;1228#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1229		break;1230	default:1231		cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc);1232		goto out;1233	}1234 1235	/*1236	 * 3. Get or update inode number (fattr->cf_uniqueid)1237	 */1238 1239	cifs_set_fattr_ino(xid, tcon, sb, inode, full_path, data, fattr);1240 1241	/*1242	 * 4. Tweak fattr based on mount options1243	 */1244#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1245handle_mnt_opt:1246#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1247	/* query for SFU type info if supported and needed */1248	if ((fattr->cf_cifsattrs & ATTR_SYSTEM) &&1249	    (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {1250		tmprc = cifs_sfu_type(fattr, full_path, cifs_sb, xid);1251		if (tmprc)1252			cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc);1253	}1254 1255	/* fill in 0777 bits from ACL */1256	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) {1257		rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode,1258				       true, full_path, fid);1259		if (rc == -EREMOTE)1260			rc = 0;1261		if (rc) {1262			cifs_dbg(FYI, "%s: Get mode from SID failed. rc=%d\n",1263				 __func__, rc);1264			goto out;1265		}1266	} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {1267		rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode,1268				       false, full_path, fid);1269		if (rc == -EREMOTE)1270			rc = 0;1271		if (rc) {1272			cifs_dbg(FYI, "%s: Getting ACL failed with error: %d\n",1273				 __func__, rc);1274			goto out;1275		}1276	} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)1277		/* fill in remaining high mode bits e.g. SUID, VTX */1278		cifs_sfu_mode(fattr, full_path, cifs_sb, xid);1279	else if (!(tcon->posix_extensions))1280		/* clear write bits if ATTR_READONLY is set */1281		if (fattr->cf_cifsattrs & ATTR_READONLY)1282			fattr->cf_mode &= ~(S_IWUGO);1283 1284 1285	/* check for Minshall+French symlinks */1286	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {1287		tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);1288		cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);1289	}1290 1291out:1292	cifs_buf_release(smb1_backup_rsp_buf);1293	cifs_put_tlink(tlink);1294	cifs_free_open_info(&tmp_data);1295	return rc;1296}1297 1298int cifs_get_inode_info(struct inode **inode,1299			const char *full_path,1300			struct cifs_open_info_data *data,1301			struct super_block *sb, int xid,1302			const struct cifs_fid *fid)1303{1304	struct cifs_fattr fattr = {};1305	int rc;1306 1307	if (is_inode_cache_good(*inode)) {1308		cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");1309		return 0;1310	}1311 1312	rc = cifs_get_fattr(data, sb, xid, fid, &fattr, inode, full_path);1313	if (rc)1314		goto out;1315 1316	rc = update_inode_info(sb, &fattr, inode);1317out:1318	kfree(fattr.cf_symlink_target);1319	return rc;1320}1321 1322static int smb311_posix_get_fattr(struct cifs_open_info_data *data,1323				  struct cifs_fattr *fattr,1324				  const char *full_path,1325				  struct super_block *sb,1326				  const unsigned int xid)1327{1328	struct cifs_open_info_data tmp_data = {};1329	struct TCP_Server_Info *server;1330	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1331	struct cifs_tcon *tcon;1332	struct tcon_link *tlink;1333	int tmprc;1334	int rc = 0;1335 1336	tlink = cifs_sb_tlink(cifs_sb);1337	if (IS_ERR(tlink))1338		return PTR_ERR(tlink);1339	tcon = tlink_tcon(tlink);1340	server = tcon->ses->server;1341 1342	/*1343	 * 1. Fetch file metadata if not provided (data)1344	 */1345	if (!data) {1346		rc = server->ops->query_path_info(xid, tcon, cifs_sb,1347						  full_path, &tmp_data);1348		data = &tmp_data;1349	}1350 1351	/*1352	 * 2. Convert it to internal cifs metadata (fattr)1353	 */1354 1355	switch (rc) {1356	case 0:1357		if (cifs_open_data_reparse(data)) {1358			rc = reparse_info_to_fattr(data, sb, xid, tcon,1359						   full_path, fattr);1360		} else {1361			smb311_posix_info_to_fattr(fattr, data, sb);1362		}1363		break;1364	case -EREMOTE:1365		/* DFS link, no metadata available on this server */1366		cifs_create_junction_fattr(fattr, sb);1367		rc = 0;1368		break;1369	case -EACCES:1370		/*1371		 * For SMB2 and later the backup intent flag1372		 * is already sent if needed on open and there1373		 * is no path based FindFirst operation to use1374		 * to retry with so nothing we can do, bail out1375		 */1376		goto out;1377	default:1378		cifs_dbg(FYI, "%s: unhandled err rc %d\n", __func__, rc);1379		goto out;1380	}1381 1382	/*1383	 * 3. Tweak fattr based on mount options1384	 */1385	/* check for Minshall+French symlinks */1386	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {1387		tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);1388		cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);1389	}1390 1391out:1392	cifs_put_tlink(tlink);1393	cifs_free_open_info(data);1394	return rc;1395}1396 1397int smb311_posix_get_inode_info(struct inode **inode,1398				const char *full_path,1399				struct cifs_open_info_data *data,1400				struct super_block *sb,1401				const unsigned int xid)1402{1403	struct cifs_fattr fattr = {};1404	int rc;1405 1406	if (is_inode_cache_good(*inode)) {1407		cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");1408		return 0;1409	}1410 1411	rc = smb311_posix_get_fattr(data, &fattr, full_path, sb, xid);1412	if (rc)1413		goto out;1414 1415	rc = update_inode_info(sb, &fattr, inode);1416	if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)1417		cifs_mark_open_handles_for_deleted_file(*inode, full_path);1418out:1419	kfree(fattr.cf_symlink_target);1420	return rc;1421}1422 1423static const struct inode_operations cifs_ipc_inode_ops = {1424	.lookup = cifs_lookup,1425};1426 1427static int1428cifs_find_inode(struct inode *inode, void *opaque)1429{1430	struct cifs_fattr *fattr = opaque;1431 1432	/* [!] The compared values must be the same in struct cifs_fscache_inode_key. */1433 1434	/* don't match inode with different uniqueid */1435	if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)1436		return 0;1437 1438	/* use createtime like an i_generation field */1439	if (CIFS_I(inode)->createtime != fattr->cf_createtime)1440		return 0;1441 1442	/* don't match inode of different type */1443	if (inode_wrong_type(inode, fattr->cf_mode))1444		return 0;1445 1446	/* if it's not a directory or has no dentries, then flag it */1447	if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry))1448		fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;1449 1450	return 1;1451}1452 1453static int1454cifs_init_inode(struct inode *inode, void *opaque)1455{1456	struct cifs_fattr *fattr = opaque;1457 1458	CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;1459	CIFS_I(inode)->createtime = fattr->cf_createtime;1460	return 0;1461}1462 1463/*1464 * walk dentry list for an inode and report whether it has aliases that1465 * are hashed. We use this to determine if a directory inode can actually1466 * be used.1467 */1468static bool1469inode_has_hashed_dentries(struct inode *inode)1470{1471	struct dentry *dentry;1472 1473	spin_lock(&inode->i_lock);1474	hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {1475		if (!d_unhashed(dentry) || IS_ROOT(dentry)) {1476			spin_unlock(&inode->i_lock);1477			return true;1478		}1479	}1480	spin_unlock(&inode->i_lock);1481	return false;1482}1483 1484/* Given fattrs, get a corresponding inode */1485struct inode *1486cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)1487{1488	unsigned long hash;1489	struct inode *inode;1490 1491retry_iget5_locked:1492	cifs_dbg(FYI, "looking for uniqueid=%llu\n", fattr->cf_uniqueid);1493 1494	/* hash down to 32-bits on 32-bit arch */1495	hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);1496 1497	inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);1498	if (inode) {1499		/* was there a potentially problematic inode collision? */1500		if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {1501			fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;1502 1503			if (inode_has_hashed_dentries(inode)) {1504				cifs_autodisable_serverino(CIFS_SB(sb));1505				iput(inode);1506				fattr->cf_uniqueid = iunique(sb, ROOT_I);1507				goto retry_iget5_locked;1508			}1509		}1510 1511		/* can't fail - see cifs_find_inode() */1512		cifs_fattr_to_inode(inode, fattr, false);1513		if (sb->s_flags & SB_NOATIME)1514			inode->i_flags |= S_NOATIME | S_NOCMTIME;1515		if (inode->i_state & I_NEW) {1516			inode->i_ino = hash;1517			cifs_fscache_get_inode_cookie(inode);1518			unlock_new_inode(inode);1519		}1520	}1521 1522	return inode;1523}1524 1525/* gets root inode */1526struct inode *cifs_root_iget(struct super_block *sb)1527{1528	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1529	struct cifs_fattr fattr = {};1530	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);1531	struct inode *inode = NULL;1532	unsigned int xid;1533	char *path = NULL;1534	int len;1535	int rc;1536 1537	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)1538	    && cifs_sb->prepath) {1539		len = strlen(cifs_sb->prepath);1540		path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL);1541		if (path == NULL)1542			return ERR_PTR(-ENOMEM);1543		path[0] = '/';1544		memcpy(path+1, cifs_sb->prepath, len);1545	} else {1546		path = kstrdup("", GFP_KERNEL);1547		if (path == NULL)1548			return ERR_PTR(-ENOMEM);1549	}1550 1551	xid = get_xid();1552	if (tcon->unix_ext) {1553		rc = cifs_get_unix_fattr(path, sb, &fattr, &inode, xid);1554		/* some servers mistakenly claim POSIX support */1555		if (rc != -EOPNOTSUPP)1556			goto iget_root;1557		cifs_dbg(VFS, "server does not support POSIX extensions\n");1558		tcon->unix_ext = false;1559	}1560 1561	convert_delimiter(path, CIFS_DIR_SEP(cifs_sb));1562	if (tcon->posix_extensions)1563		rc = smb311_posix_get_fattr(NULL, &fattr, path, sb, xid);1564	else1565		rc = cifs_get_fattr(NULL, sb, xid, NULL, &fattr, &inode, path);1566 1567iget_root:1568	if (!rc) {1569		if (fattr.cf_flags & CIFS_FATTR_JUNCTION) {1570			fattr.cf_flags &= ~CIFS_FATTR_JUNCTION;1571			cifs_autodisable_serverino(cifs_sb);1572		}1573		inode = cifs_iget(sb, &fattr);1574	}1575 1576	if (!inode) {1577		inode = ERR_PTR(rc);1578		goto out;1579	}1580 1581	if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)1582		cifs_mark_open_handles_for_deleted_file(inode, path);1583 1584	if (rc && tcon->pipe) {1585		cifs_dbg(FYI, "ipc connection - fake read inode\n");1586		spin_lock(&inode->i_lock);1587		inode->i_mode |= S_IFDIR;1588		set_nlink(inode, 2);1589		inode->i_op = &cifs_ipc_inode_ops;1590		inode->i_fop = &simple_dir_operations;1591		inode->i_uid = cifs_sb->ctx->linux_uid;1592		inode->i_gid = cifs_sb->ctx->linux_gid;1593		spin_unlock(&inode->i_lock);1594	} else if (rc) {1595		iget_failed(inode);1596		inode = ERR_PTR(rc);1597	}1598 1599out:1600	kfree(path);1601	free_xid(xid);1602	kfree(fattr.cf_symlink_target);1603	return inode;1604}1605 1606int1607cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,1608		   const char *full_path, __u32 dosattr)1609{1610	bool set_time = false;1611	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);1612	struct TCP_Server_Info *server;1613	FILE_BASIC_INFO	info_buf;1614 1615	if (attrs == NULL)1616		return -EINVAL;1617 1618	server = cifs_sb_master_tcon(cifs_sb)->ses->server;1619	if (!server->ops->set_file_info)1620		return -ENOSYS;1621 1622	info_buf.Pad = 0;1623 1624	if (attrs->ia_valid & ATTR_ATIME) {1625		set_time = true;1626		info_buf.LastAccessTime =1627			cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));1628	} else1629		info_buf.LastAccessTime = 0;1630 1631	if (attrs->ia_valid & ATTR_MTIME) {1632		set_time = true;1633		info_buf.LastWriteTime =1634		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));1635	} else1636		info_buf.LastWriteTime = 0;1637 1638	/*1639	 * Samba throws this field away, but windows may actually use it.1640	 * Do not set ctime unless other time stamps are changed explicitly1641	 * (i.e. by utimes()) since we would then have a mix of client and1642	 * server times.1643	 */1644	if (set_time && (attrs->ia_valid & ATTR_CTIME)) {1645		cifs_dbg(FYI, "CIFS - CTIME changed\n");1646		info_buf.ChangeTime =1647		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));1648	} else1649		info_buf.ChangeTime = 0;1650 1651	info_buf.CreationTime = 0;	/* don't change */1652	info_buf.Attributes = cpu_to_le32(dosattr);1653 1654	return server->ops->set_file_info(inode, full_path, &info_buf, xid);1655}1656 1657#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1658/*1659 * Open the given file (if it isn't already), set the DELETE_ON_CLOSE bit1660 * and rename it to a random name that hopefully won't conflict with1661 * anything else.1662 */1663int1664cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,1665			   const unsigned int xid)1666{1667	int oplock = 0;1668	int rc;1669	struct cifs_fid fid;1670	struct cifs_open_parms oparms;1671	struct inode *inode = d_inode(dentry);1672	struct cifsInodeInfo *cifsInode = CIFS_I(inode);1673	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);1674	struct tcon_link *tlink;1675	struct cifs_tcon *tcon;1676	__u32 dosattr, origattr;1677	FILE_BASIC_INFO *info_buf = NULL;1678 1679	tlink = cifs_sb_tlink(cifs_sb);1680	if (IS_ERR(tlink))1681		return PTR_ERR(tlink);1682	tcon = tlink_tcon(tlink);1683 1684	/*1685	 * We cannot rename the file if the server doesn't support1686	 * CAP_INFOLEVEL_PASSTHRU1687	 */1688	if (!(tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)) {1689		rc = -EBUSY;1690		goto out;1691	}1692 1693	oparms = (struct cifs_open_parms) {1694		.tcon = tcon,1695		.cifs_sb = cifs_sb,1696		.desired_access = DELETE | FILE_WRITE_ATTRIBUTES,1697		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),1698		.disposition = FILE_OPEN,1699		.path = full_path,1700		.fid = &fid,1701	};1702 1703	rc = CIFS_open(xid, &oparms, &oplock, NULL);1704	if (rc != 0)1705		goto out;1706 1707	origattr = cifsInode->cifsAttrs;1708	if (origattr == 0)1709		origattr |= ATTR_NORMAL;1710 1711	dosattr = origattr & ~ATTR_READONLY;1712	if (dosattr == 0)1713		dosattr |= ATTR_NORMAL;1714	dosattr |= ATTR_HIDDEN;1715 1716	/* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */1717	if (dosattr != origattr) {1718		info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);1719		if (info_buf == NULL) {1720			rc = -ENOMEM;1721			goto out_close;1722		}1723		info_buf->Attributes = cpu_to_le32(dosattr);1724		rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,1725					current->tgid);1726		/* although we would like to mark the file hidden1727 		   if that fails we will still try to rename it */1728		if (!rc)1729			cifsInode->cifsAttrs = dosattr;1730		else1731			dosattr = origattr; /* since not able to change them */1732	}1733 1734	/* rename the file */1735	rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL,1736				   cifs_sb->local_nls,1737				   cifs_remap(cifs_sb));1738	if (rc != 0) {1739		rc = -EBUSY;1740		goto undo_setattr;1741	}1742 1743	/* try to set DELETE_ON_CLOSE */1744	if (!test_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags)) {1745		rc = CIFSSMBSetFileDisposition(xid, tcon, true, fid.netfid,1746					       current->tgid);1747		/*1748		 * some samba versions return -ENOENT when we try to set the1749		 * file disposition here. Likely a samba bug, but work around1750		 * it for now. This means that some cifsXXX files may hang1751		 * around after they shouldn't.1752		 *1753		 * BB: remove this hack after more servers have the fix1754		 */1755		if (rc == -ENOENT)1756			rc = 0;1757		else if (rc != 0) {1758			rc = -EBUSY;1759			goto undo_rename;1760		}1761		set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags);1762	}1763 1764out_close:1765	CIFSSMBClose(xid, tcon, fid.netfid);1766out:1767	kfree(info_buf);1768	cifs_put_tlink(tlink);1769	return rc;1770 1771	/*1772	 * reset everything back to the original state. Don't bother1773	 * dealing with errors here since we can't do anything about1774	 * them anyway.1775	 */1776undo_rename:1777	CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name,1778				cifs_sb->local_nls, cifs_remap(cifs_sb));1779undo_setattr:1780	if (dosattr != origattr) {1781		info_buf->Attributes = cpu_to_le32(origattr);1782		if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid,1783					current->tgid))1784			cifsInode->cifsAttrs = origattr;1785	}1786 1787	goto out_close;1788}1789#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1790 1791/* copied from fs/nfs/dir.c with small changes */1792static void1793cifs_drop_nlink(struct inode *inode)1794{1795	spin_lock(&inode->i_lock);1796	if (inode->i_nlink > 0)1797		drop_nlink(inode);1798	spin_unlock(&inode->i_lock);1799}1800 1801/*1802 * If d_inode(dentry) is null (usually meaning the cached dentry1803 * is a negative dentry) then we would attempt a standard SMB delete, but1804 * if that fails we can not attempt the fall back mechanisms on EACCES1805 * but will return the EACCES to the caller. Note that the VFS does not call1806 * unlink on negative dentries currently.1807 */1808int cifs_unlink(struct inode *dir, struct dentry *dentry)1809{1810	int rc = 0;1811	unsigned int xid;1812	const char *full_path;1813	void *page;1814	struct inode *inode = d_inode(dentry);1815	struct cifsInodeInfo *cifs_inode;1816	struct super_block *sb = dir->i_sb;1817	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);1818	struct tcon_link *tlink;1819	struct cifs_tcon *tcon;1820	struct TCP_Server_Info *server;1821	struct iattr *attrs = NULL;1822	__u32 dosattr = 0, origattr = 0;1823 1824	cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);1825 1826	if (unlikely(cifs_forced_shutdown(cifs_sb)))1827		return -EIO;1828 1829	tlink = cifs_sb_tlink(cifs_sb);1830	if (IS_ERR(tlink))1831		return PTR_ERR(tlink);1832	tcon = tlink_tcon(tlink);1833	server = tcon->ses->server;1834 1835	xid = get_xid();1836	page = alloc_dentry_path();1837 1838	if (tcon->nodelete) {1839		rc = -EACCES;1840		goto unlink_out;1841	}1842 1843	/* Unlink can be called from rename so we can not take the1844	 * sb->s_vfs_rename_mutex here */1845	full_path = build_path_from_dentry(dentry, page);1846	if (IS_ERR(full_path)) {1847		rc = PTR_ERR(full_path);1848		goto unlink_out;1849	}1850 1851	cifs_close_deferred_file_under_dentry(tcon, full_path);1852#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1853	if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &1854				le64_to_cpu(tcon->fsUnixInfo.Capability))) {1855		rc = CIFSPOSIXDelFile(xid, tcon, full_path,1856			SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,1857			cifs_remap(cifs_sb));1858		cifs_dbg(FYI, "posix del rc %d\n", rc);1859		if ((rc == 0) || (rc == -ENOENT))1860			goto psx_del_no_retry;1861	}1862#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1863 1864retry_std_delete:1865	if (!server->ops->unlink) {1866		rc = -ENOSYS;1867		goto psx_del_no_retry;1868	}1869 1870	rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);1871 1872psx_del_no_retry:1873	if (!rc) {1874		if (inode) {1875			cifs_mark_open_handles_for_deleted_file(inode, full_path);1876			cifs_drop_nlink(inode);1877		}1878	} else if (rc == -ENOENT) {1879		d_drop(dentry);1880	} else if (rc == -EBUSY) {1881		if (server->ops->rename_pending_delete) {1882			rc = server->ops->rename_pending_delete(full_path,1883								dentry, xid);1884			if (rc == 0) {1885				cifs_mark_open_handles_for_deleted_file(inode, full_path);1886				cifs_drop_nlink(inode);1887			}1888		}1889	} else if ((rc == -EACCES) && (dosattr == 0) && inode) {1890		attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);1891		if (attrs == NULL) {1892			rc = -ENOMEM;1893			goto out_reval;1894		}1895 1896		/* try to reset dos attributes */1897		cifs_inode = CIFS_I(inode);1898		origattr = cifs_inode->cifsAttrs;1899		if (origattr == 0)1900			origattr |= ATTR_NORMAL;1901		dosattr = origattr & ~ATTR_READONLY;1902		if (dosattr == 0)1903			dosattr |= ATTR_NORMAL;1904		dosattr |= ATTR_HIDDEN;1905 1906		rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);1907		if (rc != 0)1908			goto out_reval;1909 1910		goto retry_std_delete;1911	}1912 1913	/* undo the setattr if we errored out and it's needed */1914	if (rc != 0 && dosattr != 0)1915		cifs_set_file_info(inode, attrs, xid, full_path, origattr);1916 1917out_reval:1918	if (inode) {1919		cifs_inode = CIFS_I(inode);1920		cifs_inode->time = 0;	/* will force revalidate to get info1921					   when needed */1922		inode_set_ctime_current(inode);1923	}1924	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));1925	cifs_inode = CIFS_I(dir);1926	CIFS_I(dir)->time = 0;	/* force revalidate of dir as well */1927unlink_out:1928	free_dentry_path(page);1929	kfree(attrs);1930	free_xid(xid);1931	cifs_put_tlink(tlink);1932	return rc;1933}1934 1935static int1936cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,1937		 const char *full_path, struct cifs_sb_info *cifs_sb,1938		 struct cifs_tcon *tcon, const unsigned int xid)1939{1940	int rc = 0;1941	struct inode *inode = NULL;1942 1943	if (tcon->posix_extensions) {1944		rc = smb311_posix_get_inode_info(&inode, full_path,1945						 NULL, parent->i_sb, xid);1946#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1947	} else if (tcon->unix_ext) {1948		rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,1949					      xid);1950#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */1951	} else {1952		rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,1953					 xid, NULL);1954	}1955 1956	if (rc)1957		return rc;1958 1959	if (!S_ISDIR(inode->i_mode)) {1960		/*1961		 * mkdir succeeded, but another client has managed to remove the1962		 * sucker and replace it with non-directory.  Return success,1963		 * but don't leave the child in dcache.1964		 */1965		 iput(inode);1966		 d_drop(dentry);1967		 return 0;1968	}1969	/*1970	 * setting nlink not necessary except in cases where we failed to get it1971	 * from the server or was set bogus. Also, since this is a brand new1972	 * inode, no need to grab the i_lock before setting the i_nlink.1973	 */1974	if (inode->i_nlink < 2)1975		set_nlink(inode, 2);1976	mode &= ~current_umask();1977	/* must turn on setgid bit if parent dir has it */1978	if (parent->i_mode & S_ISGID)1979		mode |= S_ISGID;1980 1981#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY1982	if (tcon->unix_ext) {1983		struct cifs_unix_set_info_args args = {1984			.mode	= mode,1985			.ctime	= NO_CHANGE_64,1986			.atime	= NO_CHANGE_64,1987			.mtime	= NO_CHANGE_64,1988			.device	= 0,1989		};1990		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {1991			args.uid = current_fsuid();1992			if (parent->i_mode & S_ISGID)1993				args.gid = parent->i_gid;1994			else1995				args.gid = current_fsgid();1996		} else {1997			args.uid = INVALID_UID; /* no change */1998			args.gid = INVALID_GID; /* no change */1999		}2000		CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,2001				       cifs_sb->local_nls,2002				       cifs_remap(cifs_sb));2003	} else {2004#else2005	{2006#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2007		struct TCP_Server_Info *server = tcon->ses->server;2008		if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&2009		    (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)2010			server->ops->mkdir_setinfo(inode, full_path, cifs_sb,2011						   tcon, xid);2012		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)2013			inode->i_mode = (mode | S_IFDIR);2014 2015		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {2016			inode->i_uid = current_fsuid();2017			if (inode->i_mode & S_ISGID)2018				inode->i_gid = parent->i_gid;2019			else2020				inode->i_gid = current_fsgid();2021		}2022	}2023	d_instantiate(dentry, inode);2024	return 0;2025}2026 2027#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2028static int2029cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,2030		 const char *full_path, struct cifs_sb_info *cifs_sb,2031		 struct cifs_tcon *tcon, const unsigned int xid)2032{2033	int rc = 0;2034	u32 oplock = 0;2035	FILE_UNIX_BASIC_INFO *info = NULL;2036	struct inode *newinode = NULL;2037	struct cifs_fattr fattr;2038 2039	info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);2040	if (info == NULL) {2041		rc = -ENOMEM;2042		goto posix_mkdir_out;2043	}2044 2045	mode &= ~current_umask();2046	rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode,2047			     NULL /* netfid */, info, &oplock, full_path,2048			     cifs_sb->local_nls, cifs_remap(cifs_sb));2049	if (rc == -EOPNOTSUPP)2050		goto posix_mkdir_out;2051	else if (rc) {2052		cifs_dbg(FYI, "posix mkdir returned 0x%x\n", rc);2053		d_drop(dentry);2054		goto posix_mkdir_out;2055	}2056 2057	if (info->Type == cpu_to_le32(-1))2058		/* no return info, go query for it */2059		goto posix_mkdir_get_info;2060	/*2061	 * BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if2062	 * need to set uid/gid.2063	 */2064 2065	cifs_unix_basic_to_fattr(&fattr, info, cifs_sb);2066	cifs_fill_uniqueid(inode->i_sb, &fattr);2067	newinode = cifs_iget(inode->i_sb, &fattr);2068	if (!newinode)2069		goto posix_mkdir_get_info;2070 2071	d_instantiate(dentry, newinode);2072 2073#ifdef CONFIG_CIFS_DEBUG22074	cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p\n",2075		 dentry, dentry, newinode);2076 2077	if (newinode->i_nlink != 2)2078		cifs_dbg(FYI, "unexpected number of links %d\n",2079			 newinode->i_nlink);2080#endif2081 2082posix_mkdir_out:2083	kfree(info);2084	return rc;2085posix_mkdir_get_info:2086	rc = cifs_mkdir_qinfo(inode, dentry, mode, full_path, cifs_sb, tcon,2087			      xid);2088	goto posix_mkdir_out;2089}2090#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2091 2092int cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,2093	       struct dentry *direntry, umode_t mode)2094{2095	int rc = 0;2096	unsigned int xid;2097	struct cifs_sb_info *cifs_sb;2098	struct tcon_link *tlink;2099	struct cifs_tcon *tcon;2100	struct TCP_Server_Info *server;2101	const char *full_path;2102	void *page;2103 2104	cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p\n",2105		 mode, inode);2106 2107	cifs_sb = CIFS_SB(inode->i_sb);2108	if (unlikely(cifs_forced_shutdown(cifs_sb)))2109		return -EIO;2110	tlink = cifs_sb_tlink(cifs_sb);2111	if (IS_ERR(tlink))2112		return PTR_ERR(tlink);2113	tcon = tlink_tcon(tlink);2114 2115	xid = get_xid();2116 2117	page = alloc_dentry_path();2118	full_path = build_path_from_dentry(direntry, page);2119	if (IS_ERR(full_path)) {2120		rc = PTR_ERR(full_path);2121		goto mkdir_out;2122	}2123 2124	server = tcon->ses->server;2125 2126	if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) {2127		rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path,2128					      cifs_sb);2129		d_drop(direntry); /* for time being always refresh inode info */2130		goto mkdir_out;2131	}2132 2133#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2134	if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &2135				le64_to_cpu(tcon->fsUnixInfo.Capability))) {2136		rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb,2137				      tcon, xid);2138		if (rc != -EOPNOTSUPP)2139			goto mkdir_out;2140	}2141#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2142 2143	if (!server->ops->mkdir) {2144		rc = -ENOSYS;2145		goto mkdir_out;2146	}2147 2148	/* BB add setting the equivalent of mode via CreateX w/ACLs */2149	rc = server->ops->mkdir(xid, inode, mode, tcon, full_path, cifs_sb);2150	if (rc) {2151		cifs_dbg(FYI, "cifs_mkdir returned 0x%x\n", rc);2152		d_drop(direntry);2153		goto mkdir_out;2154	}2155 2156	/* TODO: skip this for smb2/smb3 */2157	rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon,2158			      xid);2159mkdir_out:2160	/*2161	 * Force revalidate to get parent dir info when needed since cached2162	 * attributes are invalid now.2163	 */2164	CIFS_I(inode)->time = 0;2165	free_dentry_path(page);2166	free_xid(xid);2167	cifs_put_tlink(tlink);2168	return rc;2169}2170 2171int cifs_rmdir(struct inode *inode, struct dentry *direntry)2172{2173	int rc = 0;2174	unsigned int xid;2175	struct cifs_sb_info *cifs_sb;2176	struct tcon_link *tlink;2177	struct cifs_tcon *tcon;2178	struct TCP_Server_Info *server;2179	const char *full_path;2180	void *page = alloc_dentry_path();2181	struct cifsInodeInfo *cifsInode;2182 2183	cifs_dbg(FYI, "cifs_rmdir, inode = 0x%p\n", inode);2184 2185	xid = get_xid();2186 2187	full_path = build_path_from_dentry(direntry, page);2188	if (IS_ERR(full_path)) {2189		rc = PTR_ERR(full_path);2190		goto rmdir_exit;2191	}2192 2193	cifs_sb = CIFS_SB(inode->i_sb);2194	if (unlikely(cifs_forced_shutdown(cifs_sb))) {2195		rc = -EIO;2196		goto rmdir_exit;2197	}2198 2199	tlink = cifs_sb_tlink(cifs_sb);2200	if (IS_ERR(tlink)) {2201		rc = PTR_ERR(tlink);2202		goto rmdir_exit;2203	}2204	tcon = tlink_tcon(tlink);2205	server = tcon->ses->server;2206 2207	if (!server->ops->rmdir) {2208		rc = -ENOSYS;2209		cifs_put_tlink(tlink);2210		goto rmdir_exit;2211	}2212 2213	if (tcon->nodelete) {2214		rc = -EACCES;2215		cifs_put_tlink(tlink);2216		goto rmdir_exit;2217	}2218 2219	rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb);2220	cifs_put_tlink(tlink);2221 2222	if (!rc) {2223		spin_lock(&d_inode(direntry)->i_lock);2224		i_size_write(d_inode(direntry), 0);2225		clear_nlink(d_inode(direntry));2226		spin_unlock(&d_inode(direntry)->i_lock);2227	}2228 2229	cifsInode = CIFS_I(d_inode(direntry));2230	/* force revalidate to go get info when needed */2231	cifsInode->time = 0;2232 2233	cifsInode = CIFS_I(inode);2234	/*2235	 * Force revalidate to get parent dir info when needed since cached2236	 * attributes are invalid now.2237	 */2238	cifsInode->time = 0;2239 2240	inode_set_ctime_current(d_inode(direntry));2241	inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));2242 2243rmdir_exit:2244	free_dentry_path(page);2245	free_xid(xid);2246	return rc;2247}2248 2249static int2250cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,2251	       const char *from_path, struct dentry *to_dentry,2252	       const char *to_path)2253{2254	struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);2255	struct tcon_link *tlink;2256	struct cifs_tcon *tcon;2257	struct TCP_Server_Info *server;2258#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2259	struct cifs_fid fid;2260	struct cifs_open_parms oparms;2261	int oplock;2262#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2263	int rc;2264 2265	tlink = cifs_sb_tlink(cifs_sb);2266	if (IS_ERR(tlink))2267		return PTR_ERR(tlink);2268	tcon = tlink_tcon(tlink);2269	server = tcon->ses->server;2270 2271	if (!server->ops->rename)2272		return -ENOSYS;2273 2274	/* try path-based rename first */2275	rc = server->ops->rename(xid, tcon, from_dentry,2276				 from_path, to_path, cifs_sb);2277 2278	/*2279	 * Don't bother with rename by filehandle unless file is busy and2280	 * source. Note that cross directory moves do not work with2281	 * rename by filehandle to various Windows servers.2282	 */2283	if (rc == 0 || rc != -EBUSY)2284		goto do_rename_exit;2285 2286	/* Don't fall back to using SMB on SMB 2+ mount */2287	if (server->vals->protocol_id != 0)2288		goto do_rename_exit;2289 2290#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2291	/* open-file renames don't work across directories */2292	if (to_dentry->d_parent != from_dentry->d_parent)2293		goto do_rename_exit;2294 2295	oparms = (struct cifs_open_parms) {2296		.tcon = tcon,2297		.cifs_sb = cifs_sb,2298		/* open the file to be renamed -- we need DELETE perms */2299		.desired_access = DELETE,2300		.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),2301		.disposition = FILE_OPEN,2302		.path = from_path,2303		.fid = &fid,2304	};2305 2306	rc = CIFS_open(xid, &oparms, &oplock, NULL);2307	if (rc == 0) {2308		rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid,2309				(const char *) to_dentry->d_name.name,2310				cifs_sb->local_nls, cifs_remap(cifs_sb));2311		CIFSSMBClose(xid, tcon, fid.netfid);2312	}2313#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2314do_rename_exit:2315	if (rc == 0)2316		d_move(from_dentry, to_dentry);2317	cifs_put_tlink(tlink);2318	return rc;2319}2320 2321int2322cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,2323	     struct dentry *source_dentry, struct inode *target_dir,2324	     struct dentry *target_dentry, unsigned int flags)2325{2326	const char *from_name, *to_name;2327	void *page1, *page2;2328	struct cifs_sb_info *cifs_sb;2329	struct tcon_link *tlink;2330	struct cifs_tcon *tcon;2331	unsigned int xid;2332	int rc, tmprc;2333	int retry_count = 0;2334	FILE_UNIX_BASIC_INFO *info_buf_source = NULL;2335#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2336	FILE_UNIX_BASIC_INFO *info_buf_target;2337#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2338 2339	if (flags & ~RENAME_NOREPLACE)2340		return -EINVAL;2341 2342	cifs_sb = CIFS_SB(source_dir->i_sb);2343	if (unlikely(cifs_forced_shutdown(cifs_sb)))2344		return -EIO;2345 2346	tlink = cifs_sb_tlink(cifs_sb);2347	if (IS_ERR(tlink))2348		return PTR_ERR(tlink);2349	tcon = tlink_tcon(tlink);2350 2351	page1 = alloc_dentry_path();2352	page2 = alloc_dentry_path();2353	xid = get_xid();2354 2355	from_name = build_path_from_dentry(source_dentry, page1);2356	if (IS_ERR(from_name)) {2357		rc = PTR_ERR(from_name);2358		goto cifs_rename_exit;2359	}2360 2361	to_name = build_path_from_dentry(target_dentry, page2);2362	if (IS_ERR(to_name)) {2363		rc = PTR_ERR(to_name);2364		goto cifs_rename_exit;2365	}2366 2367	cifs_close_deferred_file_under_dentry(tcon, from_name);2368	if (d_inode(target_dentry) != NULL)2369		cifs_close_deferred_file_under_dentry(tcon, to_name);2370 2371	rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,2372			    to_name);2373 2374	if (rc == -EACCES) {2375		while (retry_count < 3) {2376			cifs_close_all_deferred_files(tcon);2377			rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,2378					    to_name);2379			if (rc != -EACCES)2380				break;2381			retry_count++;2382		}2383	}2384 2385	/*2386	 * No-replace is the natural behavior for CIFS, so skip unlink hacks.2387	 */2388	if (flags & RENAME_NOREPLACE)2389		goto cifs_rename_exit;2390 2391#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2392	if (rc == -EEXIST && tcon->unix_ext) {2393		/*2394		 * Are src and dst hardlinks of same inode? We can only tell2395		 * with unix extensions enabled.2396		 */2397		info_buf_source =2398			kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO),2399					GFP_KERNEL);2400		if (info_buf_source == NULL) {2401			rc = -ENOMEM;2402			goto cifs_rename_exit;2403		}2404 2405		info_buf_target = info_buf_source + 1;2406		tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name,2407					     info_buf_source,2408					     cifs_sb->local_nls,2409					     cifs_remap(cifs_sb));2410		if (tmprc != 0)2411			goto unlink_target;2412 2413		tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name,2414					     info_buf_target,2415					     cifs_sb->local_nls,2416					     cifs_remap(cifs_sb));2417 2418		if (tmprc == 0 && (info_buf_source->UniqueId ==2419				   info_buf_target->UniqueId)) {2420			/* same file, POSIX says that this is a noop */2421			rc = 0;2422			goto cifs_rename_exit;2423		}2424	}2425	/*2426	 * else ... BB we could add the same check for Windows by2427	 * checking the UniqueId via FILE_INTERNAL_INFO2428	 */2429 2430unlink_target:2431#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2432 2433	/* Try unlinking the target dentry if it's not negative */2434	if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {2435		if (d_is_dir(target_dentry))2436			tmprc = cifs_rmdir(target_dir, target_dentry);2437		else2438			tmprc = cifs_unlink(target_dir, target_dentry);2439		if (tmprc)2440			goto cifs_rename_exit;2441		rc = cifs_do_rename(xid, source_dentry, from_name,2442				    target_dentry, to_name);2443	}2444 2445	/* force revalidate to go get info when needed */2446	CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0;2447 2448cifs_rename_exit:2449	kfree(info_buf_source);2450	free_dentry_path(page2);2451	free_dentry_path(page1);2452	free_xid(xid);2453	cifs_put_tlink(tlink);2454	return rc;2455}2456 2457static bool2458cifs_dentry_needs_reval(struct dentry *dentry)2459{2460	struct inode *inode = d_inode(dentry);2461	struct cifsInodeInfo *cifs_i = CIFS_I(inode);2462	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);2463	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);2464	struct cached_fid *cfid = NULL;2465 2466	if (cifs_i->time == 0)2467		return true;2468 2469	if (CIFS_CACHE_READ(cifs_i))2470		return false;2471 2472	if (!lookupCacheEnabled)2473		return true;2474 2475	if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) {2476		spin_lock(&cfid->fid_lock);2477		if (cfid->time && cifs_i->time > cfid->time) {2478			spin_unlock(&cfid->fid_lock);2479			close_cached_dir(cfid);2480			return false;2481		}2482		spin_unlock(&cfid->fid_lock);2483		close_cached_dir(cfid);2484	}2485	/*2486	 * depending on inode type, check if attribute caching disabled for2487	 * files or directories2488	 */2489	if (S_ISDIR(inode->i_mode)) {2490		if (!cifs_sb->ctx->acdirmax)2491			return true;2492		if (!time_in_range(jiffies, cifs_i->time,2493				   cifs_i->time + cifs_sb->ctx->acdirmax))2494			return true;2495	} else { /* file */2496		if (!cifs_sb->ctx->acregmax)2497			return true;2498		if (!time_in_range(jiffies, cifs_i->time,2499				   cifs_i->time + cifs_sb->ctx->acregmax))2500			return true;2501	}2502 2503	/* hardlinked files w/ noserverino get "special" treatment */2504	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&2505	    S_ISREG(inode->i_mode) && inode->i_nlink != 1)2506		return true;2507 2508	return false;2509}2510 2511/**2512 * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks2513 *2514 * @key:	currently unused2515 * @mode:	the task state to sleep in2516 */2517static int2518cifs_wait_bit_killable(struct wait_bit_key *key, int mode)2519{2520	schedule();2521	if (signal_pending_state(mode, current))2522		return -ERESTARTSYS;2523	return 0;2524}2525 2526int2527cifs_revalidate_mapping(struct inode *inode)2528{2529	int rc;2530	struct cifsInodeInfo *cifs_inode = CIFS_I(inode);2531	unsigned long *flags = &cifs_inode->flags;2532	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);2533 2534	/* swapfiles are not supposed to be shared */2535	if (IS_SWAPFILE(inode))2536		return 0;2537 2538	rc = wait_on_bit_lock_action(flags, CIFS_INO_LOCK, cifs_wait_bit_killable,2539				     TASK_KILLABLE|TASK_FREEZABLE_UNSAFE);2540	if (rc)2541		return rc;2542 2543	if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {2544		/* for cache=singleclient, do not invalidate */2545		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)2546			goto skip_invalidate;2547 2548		cifs_inode->netfs.zero_point = cifs_inode->netfs.remote_i_size;2549		rc = filemap_invalidate_inode(inode, true, 0, LLONG_MAX);2550		if (rc) {2551			cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",2552				 __func__, inode, rc);2553			set_bit(CIFS_INO_INVALID_MAPPING, flags);2554		}2555	}2556 2557skip_invalidate:2558	clear_bit_unlock(CIFS_INO_LOCK, flags);2559	smp_mb__after_atomic();2560	wake_up_bit(flags, CIFS_INO_LOCK);2561 2562	return rc;2563}2564 2565int2566cifs_zap_mapping(struct inode *inode)2567{2568	set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(inode)->flags);2569	return cifs_revalidate_mapping(inode);2570}2571 2572int cifs_revalidate_file_attr(struct file *filp)2573{2574	int rc = 0;2575	struct dentry *dentry = file_dentry(filp);2576#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2577	struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;2578#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2579 2580	if (!cifs_dentry_needs_reval(dentry))2581		return rc;2582 2583#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2584	if (tlink_tcon(cfile->tlink)->unix_ext)2585		rc = cifs_get_file_info_unix(filp);2586	else2587#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */2588		rc = cifs_get_file_info(filp);2589 2590	return rc;2591}2592 2593int cifs_revalidate_dentry_attr(struct dentry *dentry)2594{2595	unsigned int xid;2596	int rc = 0;2597	struct inode *inode = d_inode(dentry);2598	struct super_block *sb = dentry->d_sb;2599	const char *full_path;2600	void *page;2601	int count = 0;2602 2603	if (inode == NULL)2604		return -ENOENT;2605 2606	if (!cifs_dentry_needs_reval(dentry))2607		return rc;2608 2609	xid = get_xid();2610 2611	page = alloc_dentry_path();2612	full_path = build_path_from_dentry(dentry, page);2613	if (IS_ERR(full_path)) {2614		rc = PTR_ERR(full_path);2615		goto out;2616	}2617 2618	cifs_dbg(FYI, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld\n",2619		 full_path, inode, inode->i_count.counter,2620		 dentry, cifs_get_time(dentry), jiffies);2621 2622again:2623	if (cifs_sb_master_tcon(CIFS_SB(sb))->posix_extensions) {2624		rc = smb311_posix_get_inode_info(&inode, full_path,2625						 NULL, sb, xid);2626	} else if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) {2627		rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);2628	} else {2629		rc = cifs_get_inode_info(&inode, full_path, NULL, sb,2630					 xid, NULL);2631	}2632	if (rc == -EAGAIN && count++ < 10)2633		goto again;2634out:2635	free_dentry_path(page);2636	free_xid(xid);2637 2638	return rc;2639}2640 2641int cifs_revalidate_file(struct file *filp)2642{2643	int rc;2644	struct inode *inode = file_inode(filp);2645 2646	rc = cifs_revalidate_file_attr(filp);2647	if (rc)2648		return rc;2649 2650	return cifs_revalidate_mapping(inode);2651}2652 2653/* revalidate a dentry's inode attributes */2654int cifs_revalidate_dentry(struct dentry *dentry)2655{2656	int rc;2657	struct inode *inode = d_inode(dentry);2658 2659	rc = cifs_revalidate_dentry_attr(dentry);2660	if (rc)2661		return rc;2662 2663	return cifs_revalidate_mapping(inode);2664}2665 2666int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,2667		 struct kstat *stat, u32 request_mask, unsigned int flags)2668{2669	struct dentry *dentry = path->dentry;2670	struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);2671	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);2672	struct inode *inode = d_inode(dentry);2673	int rc;2674 2675	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))2676		return -EIO;2677 2678	/*2679	 * We need to be sure that all dirty pages are written and the server2680	 * has actual ctime, mtime and file length.2681	 */2682	if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE | STATX_BLOCKS)) &&2683	    !CIFS_CACHE_READ(CIFS_I(inode)) &&2684	    inode->i_mapping && inode->i_mapping->nrpages != 0) {2685		rc = filemap_fdatawait(inode->i_mapping);2686		if (rc) {2687			mapping_set_error(inode->i_mapping, rc);2688			return rc;2689		}2690	}2691 2692	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_FORCE_SYNC)2693		CIFS_I(inode)->time = 0; /* force revalidate */2694 2695	/*2696	 * If the caller doesn't require syncing, only sync if2697	 * necessary (e.g. due to earlier truncate or setattr2698	 * invalidating the cached metadata)2699	 */2700	if (((flags & AT_STATX_SYNC_TYPE) != AT_STATX_DONT_SYNC) ||2701	    (CIFS_I(inode)->time == 0)) {2702		rc = cifs_revalidate_dentry_attr(dentry);2703		if (rc)2704			return rc;2705	}2706 2707	generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);2708	stat->blksize = cifs_sb->ctx->bsize;2709	stat->ino = CIFS_I(inode)->uniqueid;2710 2711	/* old CIFS Unix Extensions doesn't return create time */2712	if (CIFS_I(inode)->createtime) {2713		stat->result_mask |= STATX_BTIME;2714		stat->btime =2715		      cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime));2716	}2717 2718	stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED);2719	if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_COMPRESSED)2720		stat->attributes |= STATX_ATTR_COMPRESSED;2721	if (CIFS_I(inode)->cifsAttrs & FILE_ATTRIBUTE_ENCRYPTED)2722		stat->attributes |= STATX_ATTR_ENCRYPTED;2723 2724	/*2725	 * If on a multiuser mount without unix extensions or cifsacl being2726	 * enabled, and the admin hasn't overridden them, set the ownership2727	 * to the fsuid/fsgid of the current process.2728	 */2729	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&2730	    !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&2731	    !tcon->unix_ext) {2732		if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))2733			stat->uid = current_fsuid();2734		if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))2735			stat->gid = current_fsgid();2736	}2737	return 0;2738}2739 2740int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,2741		u64 len)2742{2743	struct cifsInodeInfo *cifs_i = CIFS_I(inode);2744	struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->netfs.inode.i_sb);2745	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);2746	struct TCP_Server_Info *server = tcon->ses->server;2747	struct cifsFileInfo *cfile;2748	int rc;2749 2750	if (unlikely(cifs_forced_shutdown(cifs_sb)))2751		return -EIO;2752 2753	/*2754	 * We need to be sure that all dirty pages are written as they2755	 * might fill holes on the server.2756	 */2757	if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping &&2758	    inode->i_mapping->nrpages != 0) {2759		rc = filemap_fdatawait(inode->i_mapping);2760		if (rc) {2761			mapping_set_error(inode->i_mapping, rc);2762			return rc;2763		}2764	}2765 2766	cfile = find_readable_file(cifs_i, false);2767	if (cfile == NULL)2768		return -EINVAL;2769 2770	if (server->ops->fiemap) {2771		rc = server->ops->fiemap(tcon, cfile, fei, start, len);2772		cifsFileInfo_put(cfile);2773		return rc;2774	}2775 2776	cifsFileInfo_put(cfile);2777	return -EOPNOTSUPP;2778}2779 2780int cifs_truncate_page(struct address_space *mapping, loff_t from)2781{2782	pgoff_t index = from >> PAGE_SHIFT;2783	unsigned offset = from & (PAGE_SIZE - 1);2784	struct page *page;2785	int rc = 0;2786 2787	page = grab_cache_page(mapping, index);2788	if (!page)2789		return -ENOMEM;2790 2791	zero_user_segment(page, offset, PAGE_SIZE);2792	unlock_page(page);2793	put_page(page);2794	return rc;2795}2796 2797void cifs_setsize(struct inode *inode, loff_t offset)2798{2799	struct cifsInodeInfo *cifs_i = CIFS_I(inode);2800 2801	spin_lock(&inode->i_lock);2802	i_size_write(inode, offset);2803	spin_unlock(&inode->i_lock);2804 2805	/* Cached inode must be refreshed on truncate */2806	cifs_i->time = 0;2807	truncate_pagecache(inode, offset);2808}2809 2810static int2811cifs_set_file_size(struct inode *inode, struct iattr *attrs,2812		   unsigned int xid, const char *full_path, struct dentry *dentry)2813{2814	int rc;2815	struct cifsFileInfo *open_file;2816	struct cifsInodeInfo *cifsInode = CIFS_I(inode);2817	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);2818	struct tcon_link *tlink = NULL;2819	struct cifs_tcon *tcon = NULL;2820	struct TCP_Server_Info *server;2821 2822	/*2823	 * To avoid spurious oplock breaks from server, in the case of2824	 * inodes that we already have open, avoid doing path based2825	 * setting of file size if we can do it by handle.2826	 * This keeps our caching token (oplock) and avoids timeouts2827	 * when the local oplock break takes longer to flush2828	 * writebehind data than the SMB timeout for the SetPathInfo2829	 * request would allow2830	 */2831	open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);2832	if (open_file) {2833		tcon = tlink_tcon(open_file->tlink);2834		server = tcon->ses->server;2835		if (server->ops->set_file_size)2836			rc = server->ops->set_file_size(xid, tcon, open_file,2837							attrs->ia_size, false);2838		else2839			rc = -ENOSYS;2840		cifsFileInfo_put(open_file);2841		cifs_dbg(FYI, "SetFSize for attrs rc = %d\n", rc);2842	} else2843		rc = -EINVAL;2844 2845	if (!rc)2846		goto set_size_out;2847 2848	if (tcon == NULL) {2849		tlink = cifs_sb_tlink(cifs_sb);2850		if (IS_ERR(tlink))2851			return PTR_ERR(tlink);2852		tcon = tlink_tcon(tlink);2853		server = tcon->ses->server;2854	}2855 2856	/*2857	 * Set file size by pathname rather than by handle either because no2858	 * valid, writeable file handle for it was found or because there was2859	 * an error setting it by handle.2860	 */2861	if (server->ops->set_path_size)2862		rc = server->ops->set_path_size(xid, tcon, full_path,2863						attrs->ia_size, cifs_sb, false, dentry);2864	else2865		rc = -ENOSYS;2866	cifs_dbg(FYI, "SetEOF by path (setattrs) rc = %d\n", rc);2867 2868	if (tlink)2869		cifs_put_tlink(tlink);2870 2871set_size_out:2872	if (rc == 0) {2873		netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true);2874		cifs_setsize(inode, attrs->ia_size);2875		/*2876		 * i_blocks is not related to (i_size / i_blksize), but instead2877		 * 512 byte (2**9) size is required for calculating num blocks.2878		 * Until we can query the server for actual allocation size,2879		 * this is best estimate we have for blocks allocated for a file2880		 * Number of blocks must be rounded up so size 1 is not 0 blocks2881		 */2882		inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9;2883 2884		/*2885		 * The man page of truncate says if the size changed,2886		 * then the st_ctime and st_mtime fields for the file2887		 * are updated.2888		 */2889		attrs->ia_ctime = attrs->ia_mtime = current_time(inode);2890		attrs->ia_valid |= ATTR_CTIME | ATTR_MTIME;2891 2892		cifs_truncate_page(inode->i_mapping, inode->i_size);2893	}2894 2895	return rc;2896}2897 2898#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY2899static int2900cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)2901{2902	int rc;2903	unsigned int xid;2904	const char *full_path;2905	void *page = alloc_dentry_path();2906	struct inode *inode = d_inode(direntry);2907	struct cifsInodeInfo *cifsInode = CIFS_I(inode);2908	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);2909	struct tcon_link *tlink;2910	struct cifs_tcon *pTcon;2911	struct cifs_unix_set_info_args *args = NULL;2912	struct cifsFileInfo *open_file;2913 2914	cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x\n",2915		 direntry, attrs->ia_valid);2916 2917	xid = get_xid();2918 2919	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)2920		attrs->ia_valid |= ATTR_FORCE;2921 2922	rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs);2923	if (rc < 0)2924		goto out;2925 2926	full_path = build_path_from_dentry(direntry, page);2927	if (IS_ERR(full_path)) {2928		rc = PTR_ERR(full_path);2929		goto out;2930	}2931 2932	/*2933	 * Attempt to flush data before changing attributes. We need to do2934	 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the2935	 * ownership or mode then we may also need to do this. Here, we take2936	 * the safe way out and just do the flush on all setattr requests. If2937	 * the flush returns error, store it to report later and continue.2938	 *2939	 * BB: This should be smarter. Why bother flushing pages that2940	 * will be truncated anyway? Also, should we error out here if2941	 * the flush returns error?2942	 */2943	rc = filemap_write_and_wait(inode->i_mapping);2944	if (is_interrupt_error(rc)) {2945		rc = -ERESTARTSYS;2946		goto out;2947	}2948 2949	mapping_set_error(inode->i_mapping, rc);2950	rc = 0;2951 2952	if (attrs->ia_valid & ATTR_SIZE) {2953		rc = cifs_set_file_size(inode, attrs, xid, full_path, direntry);2954		if (rc != 0)2955			goto out;2956	}2957 2958	/* skip mode change if it's just for clearing setuid/setgid */2959	if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))2960		attrs->ia_valid &= ~ATTR_MODE;2961 2962	args = kmalloc(sizeof(*args), GFP_KERNEL);2963	if (args == NULL) {2964		rc = -ENOMEM;2965		goto out;2966	}2967 2968	/* set up the struct */2969	if (attrs->ia_valid & ATTR_MODE)2970		args->mode = attrs->ia_mode;2971	else2972		args->mode = NO_CHANGE_64;2973 2974	if (attrs->ia_valid & ATTR_UID)2975		args->uid = attrs->ia_uid;2976	else2977		args->uid = INVALID_UID; /* no change */2978 2979	if (attrs->ia_valid & ATTR_GID)2980		args->gid = attrs->ia_gid;2981	else2982		args->gid = INVALID_GID; /* no change */2983 2984	if (attrs->ia_valid & ATTR_ATIME)2985		args->atime = cifs_UnixTimeToNT(attrs->ia_atime);2986	else2987		args->atime = NO_CHANGE_64;2988 2989	if (attrs->ia_valid & ATTR_MTIME)2990		args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);2991	else2992		args->mtime = NO_CHANGE_64;2993 2994	if (attrs->ia_valid & ATTR_CTIME)2995		args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);2996	else2997		args->ctime = NO_CHANGE_64;2998 2999	args->device = 0;3000	open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);3001	if (open_file) {3002		u16 nfid = open_file->fid.netfid;3003		u32 npid = open_file->pid;3004		pTcon = tlink_tcon(open_file->tlink);3005		rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);3006		cifsFileInfo_put(open_file);3007	} else {3008		tlink = cifs_sb_tlink(cifs_sb);3009		if (IS_ERR(tlink)) {3010			rc = PTR_ERR(tlink);3011			goto out;3012		}3013		pTcon = tlink_tcon(tlink);3014		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,3015				    cifs_sb->local_nls,3016				    cifs_remap(cifs_sb));3017		cifs_put_tlink(tlink);3018	}3019 3020	if (rc)3021		goto out;3022 3023	if ((attrs->ia_valid & ATTR_SIZE) &&3024	    attrs->ia_size != i_size_read(inode)) {3025		truncate_setsize(inode, attrs->ia_size);3026		netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true);3027		fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size);3028	}3029 3030	setattr_copy(&nop_mnt_idmap, inode, attrs);3031	mark_inode_dirty(inode);3032 3033	/* force revalidate when any of these times are set since some3034	   of the fs types (eg ext3, fat) do not have fine enough3035	   time granularity to match protocol, and we do not have a3036	   a way (yet) to query the server fs's time granularity (and3037	   whether it rounds times down).3038	*/3039	if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))3040		cifsInode->time = 0;3041out:3042	kfree(args);3043	free_dentry_path(page);3044	free_xid(xid);3045	return rc;3046}3047#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */3048 3049static int3050cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)3051{3052	unsigned int xid;3053	kuid_t uid = INVALID_UID;3054	kgid_t gid = INVALID_GID;3055	struct inode *inode = d_inode(direntry);3056	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);3057	struct cifsInodeInfo *cifsInode = CIFS_I(inode);3058	struct cifsFileInfo *wfile;3059	struct cifs_tcon *tcon;3060	const char *full_path;3061	void *page = alloc_dentry_path();3062	int rc = -EACCES;3063	__u32 dosattr = 0;3064	__u64 mode = NO_CHANGE_64;3065 3066	xid = get_xid();3067 3068	cifs_dbg(FYI, "setattr on file %pd attrs->ia_valid 0x%x\n",3069		 direntry, attrs->ia_valid);3070 3071	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)3072		attrs->ia_valid |= ATTR_FORCE;3073 3074	rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs);3075	if (rc < 0)3076		goto cifs_setattr_exit;3077 3078	full_path = build_path_from_dentry(direntry, page);3079	if (IS_ERR(full_path)) {3080		rc = PTR_ERR(full_path);3081		goto cifs_setattr_exit;3082	}3083 3084	/*3085	 * Attempt to flush data before changing attributes. We need to do3086	 * this for ATTR_SIZE and ATTR_MTIME.  If the flush of the data3087	 * returns error, store it to report later and continue.3088	 *3089	 * BB: This should be smarter. Why bother flushing pages that3090	 * will be truncated anyway? Also, should we error out here if3091	 * the flush returns error? Do we need to check for ATTR_MTIME_SET flag?3092	 */3093	if (attrs->ia_valid & (ATTR_MTIME | ATTR_SIZE | ATTR_CTIME)) {3094		rc = filemap_write_and_wait(inode->i_mapping);3095		if (is_interrupt_error(rc)) {3096			rc = -ERESTARTSYS;3097			goto cifs_setattr_exit;3098		}3099		mapping_set_error(inode->i_mapping, rc);3100	}3101 3102	rc = 0;3103 3104	if ((attrs->ia_valid & ATTR_MTIME) &&3105	    !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {3106		rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile);3107		if (!rc) {3108			tcon = tlink_tcon(wfile->tlink);3109			rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid);3110			cifsFileInfo_put(wfile);3111			if (rc)3112				goto cifs_setattr_exit;3113		} else if (rc != -EBADF)3114			goto cifs_setattr_exit;3115		else3116			rc = 0;3117	}3118 3119	if (attrs->ia_valid & ATTR_SIZE) {3120		rc = cifs_set_file_size(inode, attrs, xid, full_path, direntry);3121		if (rc != 0)3122			goto cifs_setattr_exit;3123	}3124 3125	if (attrs->ia_valid & ATTR_UID)3126		uid = attrs->ia_uid;3127 3128	if (attrs->ia_valid & ATTR_GID)3129		gid = attrs->ia_gid;3130 3131	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||3132	    (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {3133		if (uid_valid(uid) || gid_valid(gid)) {3134			mode = NO_CHANGE_64;3135			rc = id_mode_to_cifs_acl(inode, full_path, &mode,3136							uid, gid);3137			if (rc) {3138				cifs_dbg(FYI, "%s: Setting id failed with error: %d\n",3139					 __func__, rc);3140				goto cifs_setattr_exit;3141			}3142		}3143	} else3144	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))3145		attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);3146 3147	/* skip mode change if it's just for clearing setuid/setgid */3148	if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))3149		attrs->ia_valid &= ~ATTR_MODE;3150 3151	if (attrs->ia_valid & ATTR_MODE) {3152		mode = attrs->ia_mode;3153		rc = 0;3154		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||3155		    (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {3156			rc = id_mode_to_cifs_acl(inode, full_path, &mode,3157						INVALID_UID, INVALID_GID);3158			if (rc) {3159				cifs_dbg(FYI, "%s: Setting ACL failed with error: %d\n",3160					 __func__, rc);3161				goto cifs_setattr_exit;3162			}3163 3164			/*3165			 * In case of CIFS_MOUNT_CIFS_ACL, we cannot support all modes.3166			 * Pick up the actual mode bits that were set.3167			 */3168			if (mode != attrs->ia_mode)3169				attrs->ia_mode = mode;3170		} else3171		if (((mode & S_IWUGO) == 0) &&3172		    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {3173 3174			dosattr = cifsInode->cifsAttrs | ATTR_READONLY;3175 3176			/* fix up mode if we're not using dynperm */3177			if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)3178				attrs->ia_mode = inode->i_mode & ~S_IWUGO;3179		} else if ((mode & S_IWUGO) &&3180			   (cifsInode->cifsAttrs & ATTR_READONLY)) {3181 3182			dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;3183			/* Attributes of 0 are ignored */3184			if (dosattr == 0)3185				dosattr |= ATTR_NORMAL;3186 3187			/* reset local inode permissions to normal */3188			if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {3189				attrs->ia_mode &= ~(S_IALLUGO);3190				if (S_ISDIR(inode->i_mode))3191					attrs->ia_mode |=3192						cifs_sb->ctx->dir_mode;3193				else3194					attrs->ia_mode |=3195						cifs_sb->ctx->file_mode;3196			}3197		} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {3198			/* ignore mode change - ATTR_READONLY hasn't changed */3199			attrs->ia_valid &= ~ATTR_MODE;3200		}3201	}3202 3203	if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||3204	    ((attrs->ia_valid & ATTR_MODE) && dosattr)) {3205		rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);3206		/* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */3207 3208		/* Even if error on time set, no sense failing the call if3209		the server would set the time to a reasonable value anyway,3210		and this check ensures that we are not being called from3211		sys_utimes in which case we ought to fail the call back to3212		the user when the server rejects the call */3213		if ((rc) && (attrs->ia_valid &3214				(ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))3215			rc = 0;3216	}3217 3218	/* do not need local check to inode_check_ok since the server does3219	   that */3220	if (rc)3221		goto cifs_setattr_exit;3222 3223	if ((attrs->ia_valid & ATTR_SIZE) &&3224	    attrs->ia_size != i_size_read(inode)) {3225		truncate_setsize(inode, attrs->ia_size);3226		netfs_resize_file(&cifsInode->netfs, attrs->ia_size, true);3227		fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size);3228	}3229 3230	setattr_copy(&nop_mnt_idmap, inode, attrs);3231	mark_inode_dirty(inode);3232 3233cifs_setattr_exit:3234	free_xid(xid);3235	free_dentry_path(page);3236	return rc;3237}3238 3239int3240cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,3241	     struct iattr *attrs)3242{3243	struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);3244	int rc, retries = 0;3245#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY3246	struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);3247#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */3248 3249	if (unlikely(cifs_forced_shutdown(cifs_sb)))3250		return -EIO;3251 3252	do {3253#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY3254		if (pTcon->unix_ext)3255			rc = cifs_setattr_unix(direntry, attrs);3256		else3257#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */3258			rc = cifs_setattr_nounix(direntry, attrs);3259		retries++;3260	} while (is_retryable_error(rc) && retries < 2);3261 3262	/* BB: add cifs_setattr_legacy for really old servers */3263	return rc;3264}3265