MAX_TREE_SIZE + 1) +
strnlen(search_path, MAX_PATHCONF) + 1,
GFP_KERNEL);
- if (tmp_path == NULL) {
+ if (tmp_path == NULL)
return -ENOMEM;
- }
+
/* have to skip first of the double backslash of
UNC name */
strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
}
spin_lock(&inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) {
+ if (is_size_safe_to_change(cifsInfo,
+ le64_to_cpu(pfindData->EndOfFile))) {
/* can not safely shrink the file size here if the
client is writing to it due to potential races */
i_size_write(inode, le64_to_cpu(pfindData->EndOfFile));
};
/* gets root inode */
-void cifs_read_inode(struct inode *inode)
+struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
{
- int xid, rc;
+ int xid;
struct cifs_sb_info *cifs_sb;
+ struct inode *inode;
+ long rc;
+
+ inode = iget_locked(sb, ino);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+ if (!(inode->i_state & I_NEW))
+ return inode;
cifs_sb = CIFS_SB(inode->i_sb);
xid = GetXid();
inode->i_fop = &simple_dir_operations;
inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid;
+ _FreeXid(xid);
+ iget_failed(inode);
+ return ERR_PTR(rc);
}
- /* can not call macro FreeXid here since in a void func */
+ unlock_new_inode(inode);
+
+ /* can not call macro FreeXid here since in a void func
+ * TODO: This is no longer true
+ */
_FreeXid(xid);
+ return inode;
}
int cifs_unlink(struct inode *inode, struct dentry *direntry)
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
u32 oplock = 0;
- FILE_UNIX_BASIC_INFO * pInfo =
+ FILE_UNIX_BASIC_INFO *pInfo =
kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
if (pInfo == NULL) {
rc = -ENOMEM;
int cifs_revalidate(struct dentry *direntry)
{
int xid;
- int rc = 0;
+ int rc = 0, wbrc = 0;
char *full_path;
struct cifs_sb_info *cifs_sb;
struct cifsInodeInfo *cifsInode;
if (direntry->d_inode->i_mapping) {
/* do we need to lock inode until after invalidate completes
below? */
- filemap_fdatawrite(direntry->d_inode->i_mapping);
+ wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
+ if (wbrc)
+ CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
}
if (invalidate_inode) {
/* shrink_dcache not necessary now that cifs dentry ops
shrink_dcache_parent(direntry); */
if (S_ISREG(direntry->d_inode->i_mode)) {
if (direntry->d_inode->i_mapping)
- filemap_fdatawait(direntry->d_inode->i_mapping);
+ wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
+ if (wbrc)
+ CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
/* may eventually have to do this for open files too */
if (list_empty(&(cifsInode->openFileList))) {
/* changed on server - flush read ahead pages */
if (!page)
return -ENOMEM;
- zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0);
+ zero_user_segment(page, offset, PAGE_CACHE_SIZE);
unlock_page(page);
page_cache_release(page);
return rc;
/* BB check if we need to refresh inode from server now ? BB */
- /* need to flush data before changing file size on server */
- filemap_write_and_wait(direntry->d_inode->i_mapping);
-
if (attrs->ia_valid & ATTR_SIZE) {
+ /*
+ Flush data before changing file size on server. If the
+ flush returns error, store it to report later and continue.
+ BB: This should be smarter. Why bother flushing pages that
+ will be truncated anyway? Also, should we error out here if
+ the flush returns error?
+ */
+ rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
+ if (rc != 0) {
+ CIFS_I(direntry->d_inode)->write_behind_rc = rc;
+ rc = 0;
+ }
+
/* To avoid spurious oplock breaks from server, in the case of
inodes that we already have open, avoid doing path based
setting of file size if we can do it by handle.
CIFS_MOUNT_MAP_SPECIAL_CHR);
else if (attrs->ia_valid & ATTR_MODE) {
rc = 0;
- if ((mode & S_IWUGO) == 0) /* not writeable */ {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
+ rc = mode_to_acl(direntry->d_inode, full_path, mode);
+ else if ((mode & S_IWUGO) == 0) {
+#else
+ if ((mode & S_IWUGO) == 0) {
+#endif
+ /* not writeable */
if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
set_dosattr = TRUE;
time_buf.Attributes =
if (time_buf.Attributes == 0)
time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
}
- /* BB to be implemented -
- via Windows security descriptors or streams */
- /* CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, uid, gid,
- cifs_sb->local_nls); */
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
+ mode_to_acl(direntry->d_inode, full_path, mode);
+#endif
}
if (attrs->ia_valid & ATTR_ATIME) {