sb->s_magic = LL_SUPER_MAGIC;
sb->s_maxbytes = MAX_LFS_FILESIZE;
sbi->ll_inode_cache_enabled = 1;
- sbi->ll_namelen = osfs->os_namelen;
+ sbi->ll_namelen = min_t(u32, osfs->os_namelen, NAME_MAX);
sbi->ll_mnt.mnt = current->fs->root.mnt;
sbi->ll_mnt_ns = current->nsproxy->mnt_ns;
sfs->f_bavail = osfs.os_bavail;
sfs->f_fsid.val[0] = (__u32)fsid;
sfs->f_fsid.val[1] = (__u32)(fsid >> 32);
+ sfs->f_namelen = sbi->ll_namelen;
if (ll_i2info(de->d_inode)->lli_projid &&
test_bit(LL_SBI_STATFS_PROJECT, sbi->ll_flags) &&
test_bit(LLIF_PROJECT_INHERIT, &ll_i2info(de->d_inode)->lli_flags))
struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
ll_kset.kobj);
+ return scnprintf(buf, PAGE_SIZE, "%u\n", sbi->ll_namelen);
+}
+
+static ssize_t namelen_max_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
struct obd_statfs osfs;
+ int val;
int rc;
+ rc = kstrtoint(buffer, 10, &val);
+ if (rc)
+ return rc;
+
rc = ll_statfs_internal(sbi, &osfs, OBD_STATFS_NODELAY);
if (rc)
return rc;
- return scnprintf(buf, PAGE_SIZE, "%u\n", osfs.os_namelen);
+ if (val < 12) { /* arbitrary sanity check, but 8.3 was OK for DOS :-) */
+ CERROR("%s: cannot set max filename length %u below 12 chars\n",
+ sbi->ll_fsname, val);
+ return -ERANGE;
+ }
+
+ /* NAME_MAX is not strictly a VFS limit, but more of a convention.
+ * It would be possible to allow filenames over NAME_MAX, if the
+ * code in the client and server was fixed to allow this as well.
+ */
+ if (val > NAME_MAX) {
+ CERROR("%s: cannot set max filename length %u over VFS limit of %u chars\n",
+ sbi->ll_fsname, val, NAME_MAX);
+ return -EOVERFLOW;
+ }
+ if (val > osfs.os_namelen) {
+ CERROR("%s: cannot set max filename length %u over MDT limit of %u chars\n",
+ sbi->ll_fsname, val, osfs.os_namelen);
+ return -EOVERFLOW;
+ }
+
+ sbi->ll_namelen = val;
+
+ return count;
}
-LUSTRE_RO_ATTR(namelen_max);
+LUSTRE_RW_ATTR(namelen_max);
static ssize_t statfs_state_show(struct kobject *kobj, struct attribute *attr,
char *buf)
unsigned int flags)
{
struct lookup_intent *itp, it = { .it_op = IT_GETATTR };
+ struct ll_sb_info *sbi = ll_i2sbi(parent);
struct dentry *de = NULL;
+ if (dentry->d_name.len > sbi->ll_namelen)
+ return ERR_PTR(-ENAMETOOLONG);
+
/* VFS has locked the inode before calling this */
ll_set_inode_lock_owner(parent);
{
struct lookup_intent *it;
struct dentry *de;
- struct ll_sb_info *sbi = NULL;
+ struct ll_sb_info *sbi = ll_i2sbi(dir);
struct pcc_create_attach pca = { NULL, NULL };
int open_threshold;
int rc = 0;
ENTRY;
+ if (dentry->d_name.len > sbi->ll_namelen)
+ return -ENAMETOOLONG;
+
/* VFS has locked the inode before calling this */
ll_set_inode_lock_owner(dir);