Exemplo n.º 1
0
int cifs_dir_notify(struct file *file, unsigned long arg)
{
	int xid;
	int rc = -EINVAL;
	int oplock = FALSE;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	char *full_path = NULL;
	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
	__u16 netfid;

	if (experimEnabled == 0)
		return 0;

	xid = GetXid();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
	pTcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(file->f_dentry);
#else
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
	pTcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(file->f_path.dentry);
#endif

	if (full_path == NULL) {
		rc = -ENOMEM;
	} else {
		cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg));
		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
			GENERIC_READ | SYNCHRONIZE, FILE_SHARE_ALL, 0 /* create options */,
			&netfid, &oplock, NULL, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
		/* BB fixme - add this handle to a notify handle list */
		if (rc) {
			cFYI(1, ("Could not open directory for notify"));
		} else {
			filter = convert_to_cifs_notify_flags(arg);
			if (filter != 0) {
				rc = CIFSSMBNotify(xid, pTcon,
					0 /* no subdirs */, netfid,
					filter, file, arg & DN_MULTISHOT,
					cifs_sb->local_nls);
			} else {
				rc = -EINVAL;
			}
			/* BB add code to close file eventually (at unmount
			it would close automatically but may be a way
			to do it easily when inode freed or when
			notify info is cleared/changed */
			cFYI(1, ("notify rc %d", rc));
		}
	}

	FreeXid(xid);
	return rc;
}
Exemplo n.º 2
0
int cifs_dir_notify(struct file * file, unsigned long arg)
{
	int xid;
	int rc = -EINVAL;
	int oplock = FALSE;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	char *full_path = NULL;
	__u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
	__u16 netfid;

	xid = GetXid();
	cifs_sb = CIFS_SB(file->f_dentry->d_sb);
	pTcon = cifs_sb->tcon;

	down(&file->f_dentry->d_sb->s_vfs_rename_sem);
	full_path = build_path_from_dentry(file->f_dentry);
	up(&file->f_dentry->d_sb->s_vfs_rename_sem);

	if(full_path == NULL) {
		rc = -ENOMEM;
	} else {
		cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */
		rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, 
			GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
			&netfid, &oplock,NULL, cifs_sb->local_nls);
		/* BB fixme - add this handle to a notify handle list */
		if(rc) {
			cERROR(1,("Could not open directory for notify"));  /* BB remove BB */
		} else {
			filter = convert_to_cifs_notify_flags(arg);
			if(filter != 0) {
				rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, 
					filter, cifs_sb->local_nls);
			} else {
				rc = -EINVAL;
			}
			/* BB add code to close file eventually (at unmount
			it would close automatically but may be a way
			to do it easily when inode freed or when
			notify info is cleared/changed */
            cERROR(1,("notify rc %d",rc));
		}
	}
	
	FreeXid(xid);
	return rc;
}