Re: [PATCH] cifs: Allow mounts for paths for restricted intermediate paths

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Steve,

I have seen the nfs case mentioned during discussions but I am
not sure about the exact details.
Will dig into nfs code for details.

Regards,

Shirish

On Tue, Nov 19, 2013 at 10:42 AM, Steve French <smfrench@xxxxxxxxx> wrote:
> How does NFS handle this use case?
>
> On Tue, Nov 19, 2013 at 10:33 AM,  <shirishpargaonkar@xxxxxxxxx> wrote:
>> From: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
>>
>>
>> Allow cifs mounts for a prefixpath with intermediate paths without access,
>> so as to continue with the shared superblock model.
>>
>> For the intermediate path entries that do not allow access, create "placeholder"
>> inodes and instantiate dentries with those inodes.
>> If and when such a path entry becomes accessible it is filled with correct
>> info.
>>
>> Reference: Samba bugzilla 6950
>>
>> Signed-off-by: Shirish Pargaonkar <spargaonkar@xxxxxxxx>
>>
>> ---
>>  fs/cifs/cifsfs.c    | 17 +++++++++++++++--
>>  fs/cifs/cifsproto.h |  3 +++
>>  fs/cifs/inode.c     | 16 ++++++++++++++++
>>  3 files changed, 34 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
>> index 849f613..bce185c 100644
>> --- a/fs/cifs/cifsfs.c
>> +++ b/fs/cifs/cifsfs.c
>> @@ -584,6 +584,9 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>>         char *full_path = NULL;
>>         char *s, *p;
>>         char sep;
>> +       struct inode *dir, *phinode;
>> +       struct dentry *child;
>> +       struct cifs_fattr phfattr;
>>
>>         full_path = cifs_build_path_to_root(vol, cifs_sb,
>>                                             cifs_sb_master_tcon(cifs_sb));
>> @@ -592,13 +595,13 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>>
>>         cifs_dbg(FYI, "Get root dentry for %s\n", full_path);
>>
>> +       fill_phfattr(&phfattr, sb);
>>         sep = CIFS_DIR_SEP(cifs_sb);
>>         dentry = dget(sb->s_root);
>>         p = s = full_path;
>>
>>         do {
>> -               struct inode *dir = dentry->d_inode;
>> -               struct dentry *child;
>> +               dir = dentry->d_inode;
>>
>>                 if (!dir) {
>>                         dput(dentry);
>> @@ -626,6 +629,16 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
>>                 mutex_unlock(&dir->i_mutex);
>>                 dput(dentry);
>>                 dentry = child;
>> +               if (!IS_ERR(dentry)) {
>> +                       if (*s) {
>> +                               /* EACCESS on an intermediate dir */
>> +                               if (!dentry->d_inode) {
>> +                                       phinode = cifs_iget(sb, &phfattr);
>> +                                       if (phinode)
>> +                                               d_instantiate(dentry, phinode);
>> +                               }
>> +                       }
>> +               }
>>         } while (!IS_ERR(dentry));
>>         kfree(full_path);
>>         return dentry;
>> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
>> index aa33976..9a84e5c 100644
>> --- a/fs/cifs/cifsproto.h
>> +++ b/fs/cifs/cifsproto.h
>> @@ -498,4 +498,7 @@ void cifs_writedata_release(struct kref *refcount);
>>  int open_query_close_cifs_symlink(const unsigned char *path, char *pbuf,
>>                         unsigned int *pbytes_read, struct cifs_sb_info *cifs_sb,
>>                         unsigned int xid);
>> +
>> +extern void fill_phfattr(struct cifs_fattr *, struct super_block *);
>> +
>>  #endif                 /* _CIFSPROTO_H */
>> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
>> index 36f9ebb..4f5a09a 100644
>> --- a/fs/cifs/inode.c
>> +++ b/fs/cifs/inode.c
>> @@ -322,6 +322,22 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
>>         fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
>>  }
>>
>> +void
>> +fill_phfattr(struct cifs_fattr *cf, struct super_block *sb)
>> +{
>> +       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>> +
>> +       memset(cf, 0, sizeof(*cf));
>> +       cf->cf_uniqueid = iunique(sb, ROOT_I);
>> +       cf->cf_nlink = 1;
>> +       cf->cf_atime = CURRENT_TIME;
>> +       cf->cf_ctime = CURRENT_TIME;
>> +       cf->cf_mtime = CURRENT_TIME;
>> +       cf->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
>> +       cf->cf_uid = cifs_sb->mnt_uid;
>> +       cf->cf_gid = cifs_sb->mnt_gid;
>> +}
>> +
>>  static int
>>  cifs_get_file_info_unix(struct file *filp)
>>  {
>> --
>> 1.8.3.2
>>
>
>
>
> --
> Thanks,
>
> Steve
--
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




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux