Here's my second try. I hope there aren't missed ops which update the inode without having nlink updated. At worst, they should stop clobbering valid values, which was definitely happening before. Signed-off-by: Jim McDonough <jmcdonough@xxxxxxx> --- fs/cifs/cifsglob.h | 1 + fs/cifs/inode.c | 21 ++++++++++++++++++++- fs/cifs/readdir.c | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -712,6 +712,7 @@ struct dfs_info3_param { #define CIFS_FATTR_DELETE_PENDING 0x2 #define CIFS_FATTR_NEED_REVAL 0x4 #define CIFS_FATTR_INO_COLLISION 0x8 +#define CIFS_FATTR_MISSING_NLINK 0x10 struct cifs_fattr { u32 cf_flags; --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -118,6 +118,25 @@ cifs_revalidate_cache(struct inode *inod cifs_i->invalid_mapping = true; } +/* copy nlink to the inode, unless it wasn't provided. Provide + sane values if we don't have an existing one and none was provided */ +static void +cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) +{ + if (fattr->cf_nlink) { + inode->i_nlink = fattr->cf_nlink; + return; + } + + if ((fattr->cf_flags & CIFS_FATTR_MISSING_NLINK) && + (inode->i_state & I_NEW)) { + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) + inode->i_nlink = 2; + else + inode->i_nlink = 1; + } +} + /* populate an inode with info from a cifs_fattr struct */ void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) @@ -132,7 +151,7 @@ cifs_fattr_to_inode(struct inode *inode, inode->i_mtime = fattr->cf_mtime; inode->i_ctime = fattr->cf_ctime; inode->i_rdev = fattr->cf_rdev; - inode->i_nlink = fattr->cf_nlink; + cifs_nlink_fattr_to_inode(inode, fattr); inode->i_uid = fattr->cf_uid; inode->i_gid = fattr->cf_gid; --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -130,6 +130,9 @@ cifs_fill_common_info(struct cifs_fattr fattr->cf_dtype = DT_REG; } + /* non-unix readdir doesn't provide nlink */ + fattr->cf_flags &= CIFS_FATTR_MISSING_NLINK; + if (fattr->cf_cifsattrs & ATTR_READONLY) fattr->cf_mode &= ~S_IWUGO; -- Jim McDonough Samba Team SUSE labs jmcd at samba dot org jmcd at themcdonoughs dot org -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html